原文链接:http://tutorials.jenkov.com/java-networking/udp-datagram-sockets.html
目录:
- UDP 和 TCP的区别
- 使用DatagramSocket发送数据
- 使用DatagramSocket接收数据
如果想要使用UDP进行网络通信,可以使用java提供的DatagramSocket类。通过该类可以实现接收或发送UDP数据包。另外说明一下,UDP仍然位于IP层的上面一层。
UDP和TCP的区别
UDP的工作方式和TCP是很不同的。
当你使用TCP时,首先需要创建一个连接。成功建立连接后,TCP会保证你的数据平安到达对端,否则会通知你错误信息。
使用UDP时,UDP不保证你的数据一定会到达对端,并且,数据包的顺序也没有保证。
所以,UDP更适合一些对数据完整性要求不强的的数据传输过程。比如,网络直播。网络直播要求实时性,所以一两个数据包丢失对网络直播的影响不大,观众更希望看到实时的直播而不是准确完整无误的数据信号。
需要注意的是,当播放录像时,情况就有所不同了。和直播不同,录像更要求准确性与完整性。
使用DatagramSocket发送数据
首先,创建一个DatagramPacket对象,代码如下:
1.byte[] buffer = new byte[65508];
2.InetAddress address = InetAddress.getByName("jenkov.com");
3.
4.DatagramPacket packet = new DatagramPacket(
5. buffer, buffer.length, address, 9000);
Byte数组存放的是需要发送的数据,该数组长度为65508,意味着你最多只能发送65505个字节的数据。
InetAddress实例包含了接收端的IP地址。通过传入主机名参数,getByName()方法会返回一个InetAddress实例,这个实例中的IP地址会匹配传入的主机名称。
DatagramPacket构造器中的第二个参数是buffer.length,代表着byte数组中实际被发送的数据长度。第三个参数是传入的端口参数,该端口是接收数据的服务器正在监听的UDP端口。UDP端口和TCP端口是不同的,比如,计算机可以有不同的进程同时监听TCP的80端口和UDP的80端口。
为了发送DatagramPacket,需要创建一个DatagramSocket实例,并调用它的send()方法。如下:
1.DatagramSocket datagramSocket = new DatagramSocket();
2.datagramSocket.send(packet);
下面是一个完整示例:
1.DatagramSocket datagramSocket = new DatagramSocket();
2.
3.byte[] buffer = "0123456789".getBytes();
4.InetAddress receiverAddress = InetAddress.getLocalHost();
5.
6.DatagramPacket packet = new DatagramPacket(
7. buffer, buffer.length, receiverAddress, 80);
8.datagramSocket.send(packet);
使用DatagramSocket接收数据
创建一个DatagramPacket,调用datagramSocket.receive()方法将数据保存到该packet中,代码如下:
1.DatagramSocket datagramSocket = new DatagramSocket(80);
2.
3.byte[] buffer = new byte[10];
4.DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
5.
6.datagramSocket.receive(packet);
注意:
1、DatagramSocket构造器的参数80,代表UDP端口,DatagramSocket使用该端口接收UDP数据包。
2、DatagramPacket构造器参数中没有receiverAddress和端口号,这是因为我们需要用它来接收数据,而不是发送数据。
3、直到接收到DatagramPacket,receive()方法都是阻塞的。
接收到的数据会被存入byte数组中,可以调用packet的getData()方法获取该数组。如下:
1.byte[] buffer = packet.getData();
缓冲区中的数据大小取决于使用的具体UDP协议。一个具体的UDP协议应指定每个UDP数据包发送多少数据,或者指定一个可查找的数据结束标记。
真正的服务器程序可能会在循环中调用receive()方法,并将所有接收到的DatagramPacket传递给线程池,就像TCP服务器对传入连接进行处理一样(有关更多详细信息,请参阅Java多线程服务器)。