回显服务器
操作系统提供了一些网络通信的api(socket)。
如:
回显服务器:请求是啥?响应就是啥。
一个正常的服务器要做三件事情:
-
读取请求并解析。
-
根据请求计算响应。
-
把响应写回给客户端。
服务器对象
第一步:创建socket对象,并初始化。
这里的port是服务器的端口号。
第二步:读取请求并解析。
这里的一个包的大小自己定义好了。一次读取4096个字节。
第三步:根据请求计算响应。
这里是回显服务器,所以请求是什么响应就是什么。
第四步:把响应写回给客户端。
这里调用的都是封装好的api。
第五步:创建服务器对象,启动服务器。
这里的9090就是自定义的,端口号。
以上服务端就写好了。
客户端对象
如图:
以上基本是整个代码的流程。
这里和服务器其实差不太多。
如图:
这里类的属性多了IP和Port,其实就是IP地址和端口。
总代码:
package network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
private DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动");
while(true){
//读取请求并解析。
DatagramPacket requestPacket = new DatagramPacket(new byte[4096] , 4096);
socket.receive(requestPacket);
//为了在Java代码中,方便处理,我们就可以吧上述的数据包就可以转换成String。
String request = new String(requestPacket.getData() , 0 , requestPacket.getLength());
//根据请求,计算响应.
String response = this.process(request);
//把响应写回给客户端。
DatagramPacket responsePacket = new DatagramPacket(response.getBytes() , 0 , response.getBytes().length ,
requestPacket.getSocketAddress());
socket.send(responsePacket);
System.out.printf("[%s:%d] req=%s resq=%s\n" , requestPacket.getAddress() , requestPacket.getPort(),
request , response);
}
}
public String process(String request){
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server = new UdpEchoServer(9090);
server.start();
}
}
package network;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
private DatagramSocket socket = null;
private String serverIp;
private int serverport;
public UdpEchoClient(String serverIp , int serverport) throws SocketException {
socket = new DatagramSocket();
this.serverIp = serverIp;
this.serverport = serverport;
}
public void start() throws IOException {
System.out.println("客户端启动");
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请输入,要发送的请求:");
String request = sc.next();
DatagramPacket requestPacket = new DatagramPacket(request.getBytes() , 0 , request.getBytes().length ,
InetAddress.getByName(serverIp) , serverport);
socket.send(requestPacket);
DatagramPacket responsePacket = new DatagramPacket(new byte[4090] , 4090);
socket.receive(responsePacket);
//把响应显示到控制台上
String response = new String(responsePacket.getData() , 0 , responsePacket.getLength());
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
UdpEchoClient client = new UdpEchoClient("127.0.1" , 9090);
client.start();
}
}
以上就是回显服务器的总代码。
结果如图:
字典服务器
这里的字典服务器,其实就是把解析客户端的请求进行重写就行了。
做一个字典,用map对象,来输入键值对,调用map方法进行查询。
如图:
上述的服务器,继承了回显服务器,重写了process方法就实现了。
客户端的代码不变。
代码:
package network;
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
public class UdpDictServer extends UdpEchoServer {
HashMap<String,String> dict = null;
public UdpDictServer(int port) throws SocketException {
super(port);
dict = new HashMap<>();
dict.put("hello" , "你好");
dict.put("cat" , "小猫");
dict.put("dog" , "小狗");
dict.put("pig" , "小猪");
}
@Override
public String process(String request){
return dict.getOrDefault(request , "该词汇未查询到");
}
public static void main(String[] args) throws IOException {
UdpDictServer server = new UdpDictServer(9090);
server.start();
}
}
结果如图: