Java Socket 编程

来源:互联网 发布:亚丝娜的剑数据 编辑:程序博客网 时间:2024/06/16 14:25

Socket ,套接字。一个socket 地址是有网络地址和端口号组成的通信标识符。

进程间通信操作需要一对socket .进程间通信通过在一个进程中的一个socket 与另一个进程中的另一个socket 进行数据传输完成。当一个消息执行发出后,这个消息在发送端的socket 中处于排队状态,直到下层的网络协议将这些消息发送出去。当消息到达接收端的socket 后,其也会处于排队状态,直到接收端的进程对这条消息进行了接收处理。

TCP和UDP通信
关于socket 编程有两种通信协议可进行选择。一种是数据报通信,另一种是流通信

数据报通信
即UDP(User Data Protocol 用户数据报协议)。UDP是一种无连接的协议,这意味着我们每次发送数据报时,需要同时发送本机的socket描述符和接收端的socket 描述符,因此,每次通信时都需要发送额外的数据

流通信
也叫做TCP(Transfer Control Protocol,传输控制协议)。和UDP 不同,TCP 是一种基于连接的协议。在使用流通信之前,必须在一对socket 之间建立连接。其中一个socket 作为服务器进行监听连接请求,另一个作为客户端进行连接请求。一旦两个socket建立好了连接,他们可以单向或双向进行数据传输。

下面以流通信进行代码示范

public class SocketTest {    @org.junit.Test    public void test() {        String host = "127.0.0.1";        int port = 8990;        //创建一个socket服务        ServerSocket serverSocket = null;        //创建一个socket 客户端        Socket socket = null;        try {            serverSocket = new ServerSocket(port);            socket = new Socket(host, port);            socket.setKeepAlive(true);        } catch (SocketException e) {            e.printStackTrace();        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        try {            Writer writer = new OutputStreamWriter(socket.getOutputStream());            writer.write("socket 写入");            writer.flush();            writer.close();            socket.close();        } catch (IOException e) {            e.printStackTrace();        }        try {            Socket acceptSocket = serverSocket.accept();            Reader reader = new InputStreamReader(acceptSocket.getInputStream());            char chars[] = new char[1024];            int len;            StringBuilder sb = new StringBuilder();            while ((len = reader.read(chars)) != -1) {                sb.append(new String(chars, 0, len));            }            System.out.println(sb.toString());//            DataInputStream is = new DataInputStream(acceptSocket.getInputStream()) ;//            PrintStream os = new PrintStream(acceptSocket.getOutputStream());//////            while(true){//               String  line =  is.readLine();//                os.println(line);//            }            reader.close();            acceptSocket.close();            serverSocket.close();        } catch (IOException e) {            e.printStackTrace();        }    }}

http://www.importnew.com/20245.html
TCP 套接字的生命周期如下:
1)建立TCP连接
新的Socket 实例创建后就立即能用于发送和接收数据。也就是说当Socket 实例返回时,他已经连接到了一个远程终端,并通过协议的底层实现完成了TCP消息或握手信息的交换
2)客户端连接的建立
调用Socket 的构造函数时,底层实现将创建一个套接字实例,该实例的初始状态是关闭的。

TCP开放握手也称为3次握手。通常包括3条消息:一条从客户端到服务端的连接请求,一条从服务器端到客户端的确认消息,以及另一条从客户端到服务器端的确认消息。
对于客户端来讲,一旦它接收到服务端发来的确认消息,就立即认为连接已经建立。

3)服务器端连接的建立
服务器端可以调用ServerSocket的accept方法返回客户端发送的消息。程序会在accept()方法处阻塞,以等待客户端的连接请求,一旦取得连接,便要为每个客户端的连接建立一个Socket实例来实现数据通信

4)关闭TCP 连接
close() 或shutdownOutput()方法
可能有两种情况:
1,先有一个应用程序调用close()方法或shutdownOutput(),并在另一端调用close 方法前关闭握手消息
2,两端同时调用close 方法,他们的关闭握手消息在网络上交叉传输

关于数据报通信

1)在UDP 程序中,创建DatagramPacket 实例时,如果没有指定远程主机地址和端口,则该实例用来接收数据,若指定了,用来发送数据
2)在receive()方法处阻塞,直到收到一个数据报文或等待超时,可以通过setSoTimeout()方法来指定receive()方法的最长阻塞时间
3)所有通信使用同一套接字,这点和TCP 服务器不同TCP服务器为每个成功返回的accept 创建一个新的套接字
4)DatagramSocket的每一次receive()调用最多只能接收调用一次send()方法所发送的数据,而且不同的receive()方法不会返回同一个send()方法所发送的数据

原创粉丝点击