UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。UDP的交换过程如下图所示。
前面介绍了UDP是一种面向无连接的协议,因此,在通信时发送端和接收端不用建立连接。UDP通信的过程就像是货运公司在两个码头间发送货物一样。在码头发送和接收货物时都需要使用集装箱来装载货物,UDP通信也是一样,发送和接收的数据也需要使用“集装箱”进行打包,为此JDK中提供了一个DatagramPacket类,该类的实例对象就相当于一个集装箱,用于封装UDP通信中发送或者接收的数据。
示例():
发送端:
package cn.itcast.demo1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
* 实现UDP协议的发送端:
* 实现封装数据的类 java.net.DatagramPacket 将你的数据包装 * 实现数据传输的类 java.net.DatagramSocket 将数据包发出去*
* 实现步骤:
* 1. 创建DatagramPacket对象,封装数据, 接收的地址和端口 * 2. 创建DatagramSocket
* 3. 调用DatagramSocket类方法send,发送数据包 * 4. 关闭资源*
* DatagramPacket构造方法:
* DatagramPacket(byte[] buf, int length, InetAddress address, int port)
*
* DatagramSocket构造方法:
* DatagramSocket()空参数 * 方法: send(DatagramPacket d)
*
*/
public class UDPSend {
public static void main(String[] args)throws IOException{
//创建数据包对象,封装要发送的数据,接收端IP,端口
byte[] date ="你好UDP".getBytes();
//创建InetAddress对象,封装自己的IP地址
InetAddress inet = InetAddress.getByName("127.0.0.1");
DatagramPacket dp =new DatagramPacket(date, date.length, inet,6000);
//创建DatagramSocket对象,数据包的发送和接收对象
DatagramSocket ds =new DatagramSocket();
//调用ds对象的方法send,发送数据包
ds.send(dp);
//关闭资源
ds.close();
}
}
接收端:
package com.example.mbenben.newstudy;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 实现UDP接收端 * 实现封装数据包 java.net.DatagramPacket 将数据接收 * 实现输出传输 java.net.DatagramSocket 接收数据包*
* 实现步骤:
* 1. 创建DatagramSocket对象,绑定端口号 * 要和发送端端口号一致 * 2. 创建字节数组,接收发来的数据 * 3. 创建数据包对象DatagramPacket
* 4. 调用DatagramSocket对象方法 * receive(DatagramPacket dp)接收数据,数据放在数据包中 * 5. 拆包 * 发送的IP地址 * 数据包对象DatagramPacket方法getAddress()获取的是发送端的IP地址对象 * 返回值是InetAddress对象 * 接收到的字节个数 * 数据包对象DatagramPacket方法getLength()
* 发送方的端口号 * 数据包对象DatagramPacket方法 getPort()发送端口 * 6. 关闭资源*/
public class UDPReceive {
public static void main(String[] args)throws IOException {
//创建数据包传输对象DatagramSocket 绑定端口号
DatagramSocket ds =new DatagramSocket(6000);
//创建字节数组
byte[] data =new byte[1024];
//创建数据包对象,传递字节数组
DatagramPacket dp =new DatagramPacket(data, data.length);
//调用ds对象的方法receive传递数据包
ds.receive(dp);
//获取发送端的IP地址对象
String ip=dp.getAddress().getHostAddress();
//获取发送的端口号
int port = dp.getPort();
//获取接收到的字节个数
int length = dp.getLength();
System.out.println(new String(data,0,length)+"..."+ip+":"+port);
ds.close();
}
}