服务器端
在服务器端,使用UDP也需要监听指定的端口。Java提供了DatagramSocket来实现这个功能
服务器端首先使用如下语句在指定的端口监听UDP数据包:
DatagramSocket ds = new DatagramSocket(7788);
要接收一个UDP 数据包,需要准备一个 byte[]缓冲区,并通过DatagramPacket实现接收:
byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); ds.receive(packet);
假设我们收取到的是一个Sstring,那么,通过 DatagramPacket,返回的packet.getoffset()和packet.getLength()|确定数据在缓冲区的起止位置:
String s = new String(packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8);
当服务器收到一个DatagramPacket后,通常必须立刻回复一个UDP包,因为客户端地址在DatagramPacket中,每次收到的 DatagramPacket可能是不同的客户端,如果不回复,客户端就收不到任何UDP包。发送UDP包也是通过DatagramPacket 实现的:
packet.setData(s.getBytes()); ds.send(packet);
示例代码:
DatagramSocket ds = new DatagramSocket(7788); // 监听指定端口 while (true) { // 无限循环 // 数据缓冲区: byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); ds.receive(packet); // 收取一个UDP数据包 // 收取到的数据存储在buffer中,由packet.getOffset(), packet.getLength()指定起始位置和长度 // 将其按UTF-8编码转换为String: String s = new String(packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8); // 发送数据: packet.setData(s.getBytes()); ds.send(packet); }
客户端
和服务器端相比,客户端使用UDP时,只需要直接向服务器端发送(UDP包,然后接收返回的UDP包:
DatagramSocket ds = new DatagramSocket(); ds.setSoTimeout(1000); ds.connect(InetAddress.getByName("localhost"), 7788); // 连接指定服务器和端口 // 发送: byte[] data = "Hello".getBytes(); DatagramPacket packet = new DatagramPacket(data, data.length); ds.send(packet); // 接收: byte[] buffer = new byte[1024]; packet = new DatagramPacket(buffer, buffer.length); ds.receive(packet); String resp = new String(packet.getData(), packet.getOffset(), packet.getLength()); ds.disconnect();
多人对讲机传递实例
package test2;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Scanner;
import org.apache.commons.collections4.map.HashedMap;
public class test06 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Map<String, DatagramPacket> nameList = new HashedMap<String, DatagramPacket>(){
{
put("sentPacket1",(new DatagramPacket(new byte[1024], 1024,
new InetSocketAddress("192.168.254.136", 8100))));
put("sentPacket2",(new DatagramPacket(new byte[1024], 1024,
new InetSocketAddress("192.168.254.162", 8101))));
put("sentPacket3",(new DatagramPacket(new byte[1024], 1024,
new InetSocketAddress("192.168.254.168", 8102))));
put("sentPacket4",(new DatagramPacket(new byte[1024], 1024,
new InetSocketAddress("192.168.254.158", 8103))));
}
};
try (DatagramSocket socket = new DatagramSocket(8104)) {
DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
while (true) {
while (true) {
socket.receive(receivePacket);
String receiveContent = new String(receivePacket.getData(), receivePacket.getOffset(),
receivePacket.getLength());
if (receiveContent.equals("overE")) {
System.out.println("到你发言");
break;
}
System.out.println(receivePacket.getAddress()+":" + receiveContent);
}
while (true) {
System.out.print("你说:");
String sendConten = in.nextLine();
for (int i = 1; i < nameList.size() + 1; i++) {
nameList.get("sentPacket" + i).setData(sendConten.getBytes());
socket.send(nameList.get("sentPacket" + i));
}
if (sendConten.equals("overA")||sendConten.equals("overB")||sendConten.equals("overC")||sendConten.equals("overD")) {
System.out.println("你暂时退出聊天");
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}