回显器就是一个简单的根据你发出的请求指令自动回复相同的话的机器,实现的原理是根据udp中的方法分别构造服务器和客户端
上代码~
服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class 回显器2 {
private DatagramSocket socket=null;
//port表示端口号,服务器启动时候需要关联一个端口号
//收到数据根据端口号决定把端口号给哪个进程
//port类型是int实际上是两个字节的无符号0-65535
public 回显器2(int port) throws SocketException {
socket=new DatagramSocket(port);
}
//启动服务器
public void start() throws IOException {
System.out.println("服务器启动");
//服务器是持续运行的
while (true){
//1.读取请求,当前服务器不知道客户端什么时候发送请求,receive也会阻塞,真的有请求过来了receive就会返回
//参数datagrampacket是一个输出型参数
DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);//datagrampacket需要指定一个缓冲区
//缓冲区就是一段内存空间,一般使用byte数组表示
socket.receive(requestPacket);
//把request对象内容取出来,作为一个字符串
String request=new String(requestPacket.getData(),0, requestPacket.getLength());
//2.根据请求处理响应
String response=process(request);
//3.把响应写回到客户端
//此处datagrampacket中的长度必须是字节的个数,如果直接response的长度就成了字符的个数
//当前的responsepacket在构造的时候还需要指定这个包要发给谁,就是发请求的那一方
DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length
,requestPacket.getSocketAddress());
socket.send(requestPacket);
String log=String.format("[%s,%d] req:%s;res:%s",requestPacket.getAddress().toString()
,requestPacket.getPort(),
request, response);//格式化构造字符串的方法
System.out.println(log);
//%d表示打印一个有符号的十进制整数,%s表示打印一个字符串
}
}
//根据请求计算响应,由于当前是一个回显服务,把客户端请求返回去即可
private String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
回显器2 server=new 回显器2(9090);
server.start();
}
}
客户端
//客户端
public class 回显器 {
private DatagramSocket socket=null;
private String serverIp;
private int serverPort;
//参数的ip和port指的是服务器的ip和端口
public 回显器(String serverIp,int serverPort) throws SocketException {
this.serverIp=serverIp;
this.serverPort=serverPort;
this.socket=new DatagramSocket();//不能传入serveport否则相当于把发件人电话写成了收件人电话
//如果datagramsocket构造方法没有指定端口就相当于操作系统会分配一个空闲的端口号给当前的客户端
}
public void start() throws IOException {
//1.从标准输入如如一个数据
Scanner scanner=new Scanner(System.in);
while (true) {
System.out.println("->");
String request=scanner.nextLine();
if(request.equals("exit")){
System.out.println("goodbye");
return;
}
//2.把字符串构造成一个udp请求,并发送数据
//DatagramPacket既要包含具体的数据又要包含数据是发给谁的
DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length
, InetAddress.getByName(serverIp),serverPort);//客户端的ip和端口号
socket.send(requestPacket);
//3.尝试从服务器读取响应
DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response=new String(responsePacket.getData(),0,responsePacket.getLength());
//4.显示这个结果
String log=String.format("req:%s;resp:%s\n",request,response);
System.out.println(log);
}
}
public static void main(String[] args) throws IOException {
回显器 client=new 回显器("127.0.0.1",9090);//环回ip表示主机本身,因为当前客户端和服务器在同一个主机上
client.start();
}
}