UDP Socket编程
- 一. DatagramSocket
- 二. DatagramPacket
- 三. InetSocketAddress
- 四. 执行流程
- 五. 代码示例: UDP 回显服务器
数据报套接字: 使用传输层 UDP 协议
UDP: 即 User Datagram Protocol(用户数据报协议),传输层协议。
UDP的特点:
- 无连接
- 不可靠传输
- 面向数据报
- 全双工
- 有接收缓冲区,无发送缓冲区
- 大小受限:一次最多传输64k
对于数据报来说,可简单理解为,传输的数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。
一. DatagramSocket
DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。
构造方法:
方法:
二. DatagramPacket
DatagramPacket是UDP Socket发送和接收的数据报。
构造方法:
方法:
构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。
三. InetSocketAddress
InetSocketAddress 是SocketAddress 的子类
构造方法:
四. 执行流程
对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,流程如下:
五. 代码示例: UDP 回显服务器
服务器端代码:
class UdpEchoServer {
public DatagramSocket socket;
//udp的服务器需要自己指定端口号
public UdpEchoServer(int port) throws SocketException {
socket=new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("启动服务器");
while(true){
//三个步骤
//1.接受客户端发来的请求
//先构造出数据报(盘子)
DatagramPacket requestPacket=new DatagramPacket(new byte[1024],1024);
//接收数据
socket.receive(requestPacket);//输出型参数, receive 会将数据填充到 requestPacket 中
//将数据报解析成一个字符串
String request=new String(requestPacket.getData(),0,
requestPacket.getLength(),"UTF-8");//注意这里求的长度直接用的是数据报
//2.根据请求计算出响应
String response=process(request);
DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),
response.getBytes().length,//注意长度是字节数组的长度
requestPacket.getSocketAddress());//注意要加上IP地址和端口,这里合起来写了
//3.响应返回给客户端
socket.send(responsePacket);
System.out.printf("[reqIP:%s req端口号:%d][req:%s resp:%s]\n",requestPacket.getAddress().toString(),
responsePacket.getPort(),request,response);
}
}
/**
* 根据请求计算响应, 这里面只是模拟, 直接返回了原字符串
*/
public String process(String request){
return request;
}
public static void main(String[] args) throws SocketException {
UdpEchoServer udpEchoServer=new UdpEchoServer(9090);
try {
udpEchoServer.start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
客户端代码:
class UdpEchoClient {
public DatagramSocket socket;
//服务器的IP地址和端口号,传送数据时需要知道,放在数据报中
public String serverIp;
public int ServerPort;
public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
socket=new DatagramSocket();//客户端利用系统随机分配的端口号,防止自己手动的端口号不能用
this.serverIp=serverIp;
this.ServerPort=serverPort;
}
public void start() throws IOException {
Scanner scanner=new Scanner(System.in);
while(true){
//五个步骤
//1.先接收用户输入的字符串
System.out.println("->");
String request=scanner.next();
//2.构造数据报
//注意数据报中除了数据内容还要包含服务器IP和端口
DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),
request.getBytes().length, InetAddress.getByName(serverIp),ServerPort);
//3.客户端发送数据报给服务器
socket.send(requestPacket);
//4.从服务器接收响应,并解析
DatagramPacket responsePacket=new DatagramPacket(new byte[1024],1024);
socket.receive(responsePacket);
//解析数据
String response=new String(responsePacket.getData(),0,
responsePacket.getLength(),"UTF-8");//同样注意这里求长度用的也是数据报
//5.打印在控制台上
System.out.printf("req:%s resp:%s\n",request,response);
}
}
public static void main(String[] args) throws IOException {
//如果服务器在其他机器上就需要将IP地址和端口号更改了
UdpEchoClient udpEchoClient=new UdpEchoClient("127.0.0.1",9090);
udpEchoClient.start();
}
}
好啦! 以上就是对 UDP Socket编程的讲解,希望能帮到你 !
评论区欢迎指正 !