Socket三种类型
1、流式套接字(SOCK_STREAM,TCP)
在传输层,通信方式为IP+端口,需要先建立连接,数据为字节流。
保证数据完整性,发送按顺序接收,有分包机制,内设流量控制。
常见使用:文件传送协议(FTP)
2、数据报式套接字(SOCK_DGRAM,UDP)
在传输层,通信方式为IP+端口,无连接,数据已独立包形式发送。
不保证数据完整性,无发送顺序,有分包机制,无流量控制。
常见使用:网络文件系统(NFS)
3、原始式套接字(SOCK_RAW,IP)
在网络层,通信方式为IP,无连接,允许对较低层协议直接访问。
不保证数据完整性,无发送顺序,无分包机制,无流量控制。
TCP与UDP比较:
TCP类似电话通信,UDP类似邮件通信。
UDP会保留边界信息。
UDP效率高,灵活性高。
TCP需要两倍的信息量及往返时间。
TCP套接字
Socket服务器:
1、通过端口创建ServerSocket服务。
2、创建Socket对话实例,等待客户端请求。
3、通过IO流进行通信。输入流获取客户端请求信息,输出流处理响应信息。
4、关闭Socket对话连接。
5、重新创建Socket对话实例,等待下一次客户端请求。(返回2)
Socket客户端:
1、通过地址及端口创建Socket对话。
2、通过IO流进行通信。
3、关闭Socket对话连接。
服务端代码:
/* 通过端口创建Socket服务,端口范围1~65535 */ ServerSocket ss = new ServerSocket(port); /* 循环创建对话 */ while(runFlag){ /* 创建对话,线程会阻塞等待连接 */ Socket socket = ss.accept(); /* 接收客户端信息输出流 */ InputStream is = socket.getInputStream(); /* 流处理 */ ... /* 响应客户端 */ OutputStream os = socket.getOutputStream(); /* 流处理 */ ... /* 关闭连接 */ socket.close(); }
客户端代码:
/* 通过IP及端口创建Socket对话 */ Socket socket = new Socket(host, port); /* 请求信息输出流 */ OutputStream os = socket.getOutputStream(); /* 流处理 */ ... /* 返回信息输入流 */ InputStream is = socket.getInputStream(); /* 流处理 */ ... /* 关闭连接 */ socket.close();
UDP套接字
Socket服务器:
1、通过端口创建DatagramSocket服务,等待接收客户端信息。
2、获取客户端发送的Packet包。
3、向客户端发送响应信息的Packet包。(可选)
4、继续等待客户端发送的Packet包。(收到客户端信息后返回2)
Socket客户端:
1、创建DatagramSocket对象。
2、通过数据、地址端口创建发送Packet包。
3、发送Packet包。
4、接收服务端响应的Packet包。
服务端代码:
/* 通过端口创建Socket服务,端口范围1~65535 */ DatagramSocket socket = new DatagramSocket(port); /* 初始化接收包对象 */ DatagramPacket packet = new DatagramPacket(new byte[MAX_SIZE], MAX_SIZE); /* 循环接收包 */ while(runFlag){ /* 接收包,线程会阻塞等待客户端发送 */ socket.receive(packet); /* 处理packet */ DatagramPacket send_packet = this.dealPacket(packet); /* 发送响应包 */ socket.send(send_packet); }
客户端代码:
/* 创建DatagramSocket对象 */ DatagramSocket socket = new DatagramSocket(); /* 设置超时时间 */ socket.setSoTimeout(5000); /* 通过数据信息、地址、端口创建包 */ DatagramPacket send_packet = new DatagramPacket(data, data.length, address, port); /* 初始化接收包对象 */ DatagramPacket packet = new DatagramPacket(new byte[MAX_SIZE], MAX_SIZE); /* 向服务端发送包,不管服务器是否启动,都会发送 */ socket.send(send_packet); /* 接收服务端响应包 */ socket.receive(receive_packet);
多线程TCP套接字
1、迭代服务器:单线程,按顺序响应客户端的请求。一个请求处理完毕后处理下一个。
2、并行服务器:每一个客户对应一个线程。
3、一客户一线程代码:
/* Socket处理线程 */ public class SocketThread implements Runnable { private Socket socket; public void run() { /* 流处理 */ socket.getInputStream(); socket.getOutputStream(); ... socket.close(); } }
/* Socket服务器 */ /* 通过端口创建Socket服务,端口范围1~65535 */ ServerSocket ss = new ServerSocket(port); /* 循环创建对话 */ while(runFlag){ /* 创建对话,线程会阻塞等待连接 */ Socket socket = ss.accept(); /* 创建线程处理 */ new Thread(new SocketThread(socket)).start(); }