- UDP协议--面向数据报,无连接(例如发微信)
- 核心类:Datagram Socket
- 客户端:
- 先初始化(实例化socket对象)
- 进入主循环:(1)从用户这里读取输入的数据。(2)构造请求发送给服务器。(3)从服务器读取响应。(4)把响应写回客户端。
package UDP1101;
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 {
Scanner scanner = new Scanner(System.in);
while(true) {
//1.读取用户输入的数据
System.out.println("-> ");
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());
//4.显示响应数据
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
//"127.0.0.1"特殊ip,环回ip,自己访问自己
UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}
- 服务器:
- 先初始化(实例化socket对象)
- 进入主循环,接受并处理请求:(1)读取数据并解析。(2)根据请求计算响应。(3)把响应结果写回到客户端。
package UDP1101;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
//对于一个服务器程序来说,核心流程分两步
//1.进入初始化操作,(实例化socket对象)
//2.进入主循环,接收并处理请求
//a.读取数据并解析。b.根据请求计算响应。c.把响应结果写回到客户端
private DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动");
while(true) {
//a.读取数据并解析
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
//receive会一直阻塞到有客户端发送数据过来为止.
socket.receive(requestPacket);
//把请求数据转成string(原来是byte[]),用户实际发送的数据长度可能远远小于4096,
// 而此处的getlength得到的长度就是4096,通过trim可以干掉空白字符
String request = new String(requestPacket.getData(),
0, requestPacket.getLength()).trim();
//b.根据请求计算响应
String response = process(request);
//c.把响应结果写回到客户端,响应数据就是response,需要包装成一个packet对象
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
response.getBytes().length,requestPacket.getSocketAddress());
//requestPacket.getSocketAddress(),此处的地址就是客户端的地址和端口
//response.getBytes().length得到的是字节数
socket.send(requestPacket);
//锦上添花:打印一条请求日志
System.out.printf("[%s:%d] req: %s;resp:%s\n",requestPacket.getAddress().toString(),
requestPacket.getPort(),request,response);
}
}
public String process(String request) {
//此处由于是一个echo server,请求内容是啥,响应内容就是啥
//如果是一个更复杂的服务器,此处就需要包含很多的业务逻辑来进行具体的计算
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server = new UdpEchoServer(9090);
server.start();
}
}