概述
UDP没有创建连接,数据包是一次收发一个,没有流的概念。但是在UDP编程中需要用到的是Socket,因为应用程序在使用UDP时必须指定网络接口(IP地址)和端口号。
服务器端
在服务器端,使用UDP也需要监听指定的端口。Java提供了DatagramSocket来实现这个功能。
代码实现如下:
DatagramSocket socket = new DatagramSocket(7788);//监听端口
//提前创建两个Parket数据包,分别用于接收和发送
DatagramPacket sendPacket = new DatagramPacket(new byte[1024],1024,
new InetSocketAddress("192.168.254.173",9888));//目的地
DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
while(true) {
//接收
socket.receive(receivePacket);
String receiveContent = new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
System.out.println("它说:"+receiveContent);
if(receiveContent.equals("over")) {
System.out.println("对方已经退出聊天");
return;
}
//发送
System.out.println("你说:");
String sendContent = input.nextLine();
sendPacket.setData(sendContent.getBytes());
socket.send(sendPacket);
if(sendContent.equals("over")) {
System.out.println("你已经退出聊天");
return;
}
}
注意
如果没有其他应用程序占据这个端口,那么监听工程,我们就用一个无限循环来处理收到的UDP数据包(在最外层)。
对上面的代码解释
要接收一个UDP数据包,需要准备一个byte[] 缓冲区,并通过DatagramPacket实现接收:
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
ds.receive(packet);
当服务器收到一个DatagramPacket后,通常必须立刻恢复一个或多个UDP包,因为客户端在DatagramPacket中,每次收到的DatagramPacket可能是不同的客户端,如果不回复的话,客户端就收不到任何UDP包。
发送的UDP包也是通过DatagramPacket实现的:
byte[] data = ...
packet.setData(data);
ds.send(packet);
客户端
和服务器端相比,客户端使用UDP时,只需要直接向服务器发送UDP包,然后接收返回的UDP包:
//客户端B监听8888端口
DatagramSocket socket = new DatagramSocket(9888);
//提前创建两个Parket数据包,分别用于接收和发送
DatagramPacket sendPacket1 = new DatagramPacket(new byte[1024],1024,
new InetSocketAddress("192.168.254.173",9888));//目的地
while(true) {
//发送
System.out.println("客户说:");
String sendContent = input.nextLine();
sendPacket1.setData(sendContent.getBytes());
socket.send(sendPacket1);
if(sendContent.equals("over")) {
System.out.println("你已经退出聊天");
return;
}
//接收
DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
socket.receive(receivePacket);
String receiveContent = new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
System.out.printf("对象"+"说:"+receiveContent);
if(receiveContent.equals("over")) {
System.out.println("对方已经退出聊天");
return;
}
}
客户端创建DatagramSocket实例时并不需要指定端口,而是由操作系统自动指定一个当前使用的端口。紧接着,调用setSoTimeout(10000);(超时限定) 。
如果客户希望发送两个不同的服务器发送的UDP包,那么它必须创建量的DatagramPacket实例。后续的收发数据和服务器端是一致的。
disconnect()方法并不是真正的断开连接,他只是清楚了客户端DatagramSocket实例记录的远程服务地址和端口号。