前言
这次学习的是服务端与客户端之间的Socket通信,最后完成一个Socket实现多线程下的局域网实时聊天的小demo。
基于TCP的的Socket通信
服务器端的流程大致如下:
- 创建ServerSocket对象,绑定监听端口 - 1 - ServerSocket serverSocket = new ServerSocket(port); 
- 通过accept()方法监听客户端请求 - 1 - Socket socket = serverSocket.accept(); 
- 建立连接后通过Input Stream读取客户端发送的请求信息 - 1 - inputStream = socket.getInputStream(); 
- 通过Output Stream向客户端发送响应信息 - 1 - outputStream = socket.getOutputStream(); 
- 关闭资源 
客户端的流程大致如下:
- 创建Socket对象,设定连接服务器地址与端口号 - 1 - Socket socket = new Socket("localhost", port); 
- 建立连接后,通过Output Stream向服务端发送请求信息 - 1 - OutputStream outputStream = socket.getOutputStream(); 
- 通过Input Stream获取服务器响应的信息 - 1 - InputStream inputStream = socket.getInputStream(); 
- 关闭资源 
多线程完成TCP通信
Java中有四种实现线程池的方式,我使用的cachedThreadPool(缓存线程池),用来实现服务器与多客户端间的通信,流程如下:
- 服务器端创建ServerSocket对象,绑定监听端口,循环调用accept()方法监听客户端请求 
- 客户端创建一个socket对象与服务器建立连接 
- 服务器创建一个线程池,当接收到客户端的有新的请求时在该线程池内新建一个线程并创建socket与该客户端连接 
- 完成通信后释放连接,空余线程将被保留一段时间(cachedThreadPool为60s),服务器继续等待新的连接 
基于UDP的Socket通信
服务端流程:
- 创建DatagramSocket,指定端口号 - 1 - DatagramSocket socket = new DatagramSocket(port); 
- 创建DatagramPacket - 1 
 2- byte[] data = new byte[1024]; // 1024个字节 
 DatagramPacket packet = new DatagramPacket(data, data.length);
- 接受客户端发送数据 - 1 - socket.receive(packet); 
- 读取数据 - 1 - String info = new String(data, 0, packet.getLength()); //bytes转为String 
客户端流程:
- 定义连接服务器信息与发送信息 - 1 
 2
 3- InetAddress address = InetAddress.getByName("localhost"); 
 int port = port;
 byte[] data = "test info from client".getBytes();
- 创建DatagramPacket,包含将要发送的信息 - 1 - DatagramPacket packet = new DatagramPacket(data, data.length,address,port); 
- 创建DatagramSocket - 1 - DatagramSocket socket = new DatagramSocket(); 
- 发送数据 - 1 - socket.send(packet); 
Socket实现局域网实时聊天
服务端与客户端的流程参考上面,但是有两个点需要注意。
一是服务端需要保证当一个客户端发送了新消息时,其他所有客户端上都应显示出来,即需要服务端做一个转发,同时服务端需要开启多线程处理来自每个客户端的消息。
二是需要用一个id区分每个客户端,显示的消息中如果是自己发的应该显示的是“来自自己”,其他人的消息来源则用id号标识。