前言
这次学习的是服务端与客户端之间的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
2byte[] 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
3InetAddress 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号标识。