基于UDP和TCP实现回显服务器
目录
一. UDP 回显服务器
1. UDP Echo Server
2. UDP Echo Client
二. TCP 回显服务器
1. TCP Echo Server
2. TCP Echo Client
回显服务器 (Echo Server) 就是客户端发送什么样的请求, 服务器就返回什么样的响应, 没有任何的计算和处理逻辑.
一. UDP 回显服务器
1. UDP Echo Server
下面实现服务器.
public class UdpEchoSever {
private DatagramSocket socket = null;
public UdpEchoSever(int port) throws SocketException {
socket = new DatagramSocket(port); // 创建一个DatagramSocket对象,并绑定一个端口号.
}
}
(1) 这里声明的SocketException是IOException的子类, 是网络编程中常见的异常.
(2) UdpEchoSever的构造方法方法中, 在调用DatagramSocket的构造方法时, jvm就会调用系统API, 完成 "端口号 - 进程" 的绑定.
(3) 同一时刻, 一个端口号只能绑定一个进程; 而一个进程可以绑定多个端口号.
public void start() throws IOException {
System.out.println("服务器启动!");
while (true) {
// 此处通过一个"死循环"来不停地处理客户端的请求.
// 1. 读取客户端的请求并解析.
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
// 2. 根据请求, 计算响应. (回显服务器, 响应==请求)
String response = process(request);
// 3. 把响应写回到客户端.
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(responsePacket);
// 4. 打印日志
System.out.printf("[%s:%d] req=%s, resp=%s
", requestPacket.getAddress(), requestPacket.getPort(),
request, response);
}
}
接下来我们通过start()方法编写服务器的核心流程
1. 读取客户端请求并解析
(1) 服务器的主要工作, 就是不停地处理客户端发来的请求. 所以需要写一个 while(true) 死循环来不停地处理客户端发来的请求.
(2) 这里的 receive 方法: 一调用receive方法, 就会就从网卡上读取数据, 但是此时网卡上不一定有数据, 如果网卡上有数据, receive立即返回获取到的数据; 如果网卡上没数据, receive就会阻塞等待, 一直等待到获取到数据为止. 此处receive中的的参数也是"输出型参数", 从网卡中获取到的数据会存到requestPacket里面.
(3) receive接收到的数据是二进制数据, 为了方便后续处理, 我们把它转成字符串类型的数据.
2. 根据请求, 计算响应
因为我们这里实现的是回显服务器, 所以响应 == 请求.
3. 把相应写回客户端
由于我们为了方便处理吧字节数组转成了字符串, 所以在往回发的时候需要