和TCP编程相比,UDP编程就简单得多,因为UDP没有创建连接,数据包也是一次收发一个,所以没有流的概念。
用户数据报协议(User Datagram Protocol)。 数据报(Datagram)通信有以下特点:
在Java中使用UDP编程,仍然需要使用Socket,因为应用程序在使用UDP时必须指定网络接口(IP)和端口号。注意:UDP端口和TCP端口虽然都使用0~65535,但他们是两套独立的端口,即一个应用程序用TCP占用了端口1234,不影响另一个应用程序用UDP占用端口1234。
使用UDP实现服务器给客户端群发消息(测试给两个客户端发送消息)。客户接收到消息后给服务器发送确认信息。
MyServer.java
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//服务器给客户端群发消息。
public class MyServer {
public static void main(String[] args) {
try {
//1.创建服务器端DatagramSocket
DatagramSocket server_ds = new DatagramSocket(9999);
//2.创建要发送的数据包的对象
String s = "通知:今天晚上7:00在401机房开会!";
//把这个字符串打包成一个数据包
DatagramPacket dp1 = new DatagramPacket(s.getBytes(), s.getBytes().length, InetAddress.getByName("localhost"), 7777);
DatagramPacket dp2 = new DatagramPacket(s.getBytes(), s.getBytes().length, InetAddress.getByName("localhost"), 6666);
//3.发送
server_ds.send(dp1);
server_ds.send(dp2);
//4.接收客户端的数据包
for(int i=0;i<2;i++) {
byte[] buff = new byte[1024];
DatagramPacket dp = new DatagramPacket(buff, buff.length);
server_ds.receive(dp);
System.out.println("接收的消息是:");
System.out.println(new String(dp.getData(), 0, dp.getLength()));
System.out.println(new String(" From:" + dp.getAddress() + " port:" + dp.getPort() + " length:" + dp.getLength() + "字节"));
}
//5.给服务器发送消息
//5.关闭
server_ds.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
MyClient.java
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class MyClient {
public static void main(String[] args) {
String msg = "接收完毕!";
try {
InetAddress serverIp; //服务器端的ip地址
int serverPort; //服务器的端口
//1.创建客户端的DatagramSocket
DatagramSocket client_ds = new DatagramSocket(6666);
//2.创建用字节数组
byte[] buff = new byte[1024];
//3.创建接收的数据包
DatagramPacket dp = new DatagramPacket(buff, buff.length);
//4.接收
client_ds.receive(dp);
//打印接收的消息以及相关的数据包的信息
//System.out.println(new String(dp.getData())+"From:"+dp.getAddress()+"port:"+dp.getPort()+"To:"+dp.getSocketAddress()+"length:"+dp.getLength()+"字节");
System.out.println("接收的消息是:");
System.out.println(new String(dp.getData(), 0, dp.getLength()));
System.out.println(new String(" From:" + dp.getAddress() + " port:" + dp.getPort() + " length:" + dp.getLength() + "字节"));
//5.给服务器发送消息
serverIp = dp.getAddress();
serverPort = dp.getPort();
DatagramPacket clientDataPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, serverIp, serverPort);
client_ds.send(clientDataPacket);
System.out.println("客户端回复成功");
//6.关闭
client_ds.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
先启动两个客户端,两个客户端监听端口分别指定为6666和7777,再启动服务器。
运行结果:
客户端1
接收的消息是:
通知:今天晚上7:00在401机房开会!
From:/127.0.0.1 port:9999 length:44字节
客户端回复成功
客户端2
接收的消息是:
通知:今天晚上7:00在401机房开会!
From:/127.0.0.1 port:9999 length:44字节
客户端回复成功
服务器
接收的消息是:
接收完毕!
From:/127.0.0.1 port:7777 length:13字节
接收的消息是:
接收完毕!
From:/127.0.0.1 port:6666 length:13字节