黑马程序员技术交流社区

标题: socket的使用和理解 [打印本页]

作者: 詹英鹏    时间: 2012-1-3 19:16
标题: socket的使用和理解
本帖最后由 詹英鹏 于 2012-1-4 19:25 编辑

看了毕老师的视频,网络编程那一块
对于套接字socket,看了API文档,感觉还是很抽象很难理解,老毕说了
网络编程相当重要滴,这个socket谁能给我形象一点讲一下,socket的理解
加上例子叛变有注释就更好了,谢谢
还有几天,但愿能来得及,各位我们一起加油!
作者: 闫江龙    时间: 2012-1-3 20:07
找到一个好理解的
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
下面是我忍为比较重要的API:
        1、. Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,就是接受不到需要的 就一直等待 一般循环会有这个问题
  2、. getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例,。

  3、. getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。

  注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。

  写代码时一般先写server端.
//Server

package Killva.NetWorkchaper1.o3;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TestTCPServer {
public static void main(String args[])throws IOException{
  ServerSocket ss =new ServerSocket(10000); //建立了客户端 监听一个端口 这里用了10000端口
  while(true){
   System.out.println("--------服务端已近启动------------");
      Socket s =ss.accept();
      
      DataOutputStream dos =new DataOutputStream(s.getOutputStream());
      
      System.out.println("客户端["+s.getInetAddress().getHostAddress()+ "  :"+s.getPort()+ "]已近链接!");
      dos.writeUTF("服务器端写入客户端的数据:客户端("+
               s.getInetAddress().getHostAddress()+
                "  :"+s.getPort()+
                        "]已经链接上服务器端["+
                        s.getLocalAddress().getHostName()+
                        ":"+s.getLocalPort()+
                        "]!");
      
      dos.flush();
      dos.close();
      s.close();
      
      
  }
}


}




Client端


package Killva.NetWorkchaper1.o3;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;


public class TestTCPCLient {
public static void main(String[] args) throws IOException{
  System.out.println("-------------client端-----------");
  for(long i=0;i<10;i++){
   Socket s =new Socket("192.168.1.*",10000);//IP你自己设吧   
   DataInputStream dis = new DataInputStream(s.getInputStream());
   System.out.println(""+dis.readUTF());
   dis.close();
   s.close();
  }
}
}



作者: 罗全涛    时间: 2012-1-3 20:42
我的博客里有对Tcp和UDp编程的总结。博客地址:http://blog.csdn.net/heimaatao/article/details/7169973
我把TCP的粘过来了,UDP的你到我博客里看吧。

TCP网络编程涉及到客户端和服务器端,这与UDP中的发送端和接收端有很大区别。

TCP编程首先应该要明确TCP协议的特点:需要建立连接,形成传输通路。

下面就客户端和服务器端的不同分别总结TCP网络编程:

客户端:

1:建立端点,开启socket服务,并要指定进行连接的服务器地址和端口。这主要是通过将服务器ip地址和端口作为参数来创建Socket实例s完成的。

2:通过客户端套接字s的getInputStream()和getOutputStream()获取网络输入输出流,为了提供高效率,可通过BufferedReader和BufferedWriter将网络输入输出流封装成bufIo和bufOut。注意bufIo和bufOut的名字不是随便取的,如果需求还有从键盘读入数据,或者从客户端文件中读入数据时,必然也要创建BufferedReader的实例,那么上面的取名是非常必要的。

3:如果需求有进行键盘读入或者文件读入,那么就用bufIo.readLine()方法一行一行的读取数据,然后通过bufOut.wrte(buf)将读入的数据写入到数据缓冲区中。注意这里的bufOut.wrte(buf)写入的是数据缓冲区,并没有将数据发出去,需要用flush()方法将数据发送出去。同时还要注意此时发送过去的是有效数据,换句话说是没有换行符的,在服务器端如果需要一行一行的读取数据,那么此处必须进行newLine()操作。综合起来就是:

BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

         String line = null;

         while((line=bufIn.readLine())!=null)

         {

                   bufOut.write(line.toUpperCase());

                   bufOut.newLine();//回车,结束标记

                   bufOut.flush();

         }

4:如果进行了文件读取,就要关闭文件时用到的读取流,如果没有就关闭套接字s,s的关闭会自动的将bufIn 、bufOut进行关闭,因为bufIn 、bufOut全都依赖于套接字s。一旦s不存在,这两个流也就不存在了。



服务器端TCP网络编程的步骤:

1:和客户端一样,开启服务,不过此时用到的是ServerSocket来创建实例ss,创建ss的时候还应该指定一个该套接字要进行监听的端口。这个端口应该和客户端套接字中连接服务器是的端口一致,以确保数据能够被服务器收到。

2:通过ss的方法

Socket
accept()
          侦听并接受到此套接字的连接。


来获取客户端套接字s的实例对象

         Soceket  s =  ss.accept();

3: 通过客户端套接字s的getInputStream()和getOutputStream()获取网络输入输出流,为了提供高效率,可通过BufferedReader和BufferedWriter将网络输入输出流封装成bufIo和bufOut。然后通过bufIo.readLine()进行一行一行的读取,如果需求中有需要通过服务器的处理后还要将这些数据再发送回客户端,那么就通过bufOut.write();方法将数据发回客户端,注意此处发过去的也是有效数据,在某些情况下也要进行newLine()。同时此处还只是将数据发送到数据缓冲区,需要调用flush()方法进行刷新。综合如下:

BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

         String line = null;

         while((line=bufIn.readLine())!=null)

         {

                   bufOut.write(line.toUpperCase());

                   bufOut.newLine();//回车,结束标记

                   bufOut.flush();

         }

4:关闭资源






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2