import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
//客户端的主要流程
//1、从用户这里读取输入数据
//2、构造请求发送给服务器
//3、从服务器读取响应
//4、把响应写回给客户端
private DatagramSocket socket = null;
private String serverIp;
private int serverPort;
//需要在启动客户端的时候来确定连接哪个服务器
public UdpEchoClient(String serverIp, int serverPort) throws SocketException {
this.serverIp = serverIp;
this.serverPort = serverPort;
socket = new DatagramSocket();//客户端不用绑定端口,服务器必须绑定端口
//一个端口号,通常情况下只能被一个进程绑定
//服务器绑定端口,客户端才能访问
}
public void start() throws IOException {
//1、从用户这里读取输入数据
System.out.println("客户端启动");
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("->");
String request = scanner.nextLine();
if (request.equals("exit")) {
break;
}
//2、构造请求发送给服务器
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),
request.getBytes().length,
InetAddress.getByName(serverIp),serverPort);
socket.send(requestPacket);
//3、从服务器读取响应
DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(), 0, responsePacket.getLength()).trim();
//4、显示响应数据
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
class UdpEchoServer {
//对于一个服务器程序来说,核心流程分为两步
//1、进行初始化操作(实例化Socket)
//2、进入主循环(死循环),接收并处理请求
// 2.1读取数据并解析
// 2.2根据请求计算响应
// 2.3把响应结果写回到客户端
public DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
//new这个socket对象的时候
// 就会让当前的socket对象和一个ip地址以及一个端口号关联起来(绑定端口)
//未来客户端就按照这个ip+端口来访问服务器
//构造socket的时候如果没写ip,默认是0.0.0.0 特殊IP -- 会关联到这个主机所有网卡的IP
}
public void start() throws IOException {
System.out.println("服务器启动");
while (true) {
//读取数据并解析
//DatagramPacket 是upd发送接收数据的基本单位
DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(), 0,
requestPacket.getLength()).trim();
//用户实际发送的数据可能远远小于4096
//此处getLength得到的长度就是4096,trim可以去掉不必要的空白字符
//根据请求计算响应
String response = process(request);
//把响应结果写回到客户端
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
response.getBytes().length, requestPacket.getSocketAddress());
//requestPacket.getSocketAddress()
// 这个包要发给谁(目的IP和端口),此处的地址就是客户端的地址和端口
//这两个信息包含在requestPacket内部
socket.send(responsePacket);
//打印一条请求日志
System.out.printf("[%s:%d] req: %s; resp: %s\n",responsePacket.getAddress()
.toString(), requestPacket.getPort(), request,response);
}
}
public String process (String request) {
//此处是一个echo server,请求内容是啥,响应内容就是啥
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer updEchoServer = new UdpEchoServer(9090);
updEchoServer.start();
}
}