基于UDP协议的Socket编程

UDP即(user datagram protocal,用户数据报协议),我们很多人应该都了解过TCP(transp control protocal,传输控制协议),那么可能有人会问了,为什么有了TCP协议还要UDP协议呢?

这是由于UDP协议和TCP协议之间不同的特点,决定了这两种协议的适合的应用场景的不同。接下来就由我来为大家介绍一下UDP协议,并给出UDP编程的Java实现。

一、UDP协议

用户数据报协议(UDP,User Datagram Protocal)是一种面向无连接的传输层协议,提供不可靠的数据传输服务。
无连接是指:
在传输数据之前客户端和服务器端并不建立连接。
不可靠是指:
1、并不保证数据包完全发送出去。
2、不保证数据包能被接收方接收。
3、也不保证接收方接收到的数据包的顺序和发送方的发送顺序一致。

那么为什么这么不负责的协议还有存在的意义呢?原来UDP协议的无连接不可靠特性是牺牲了可靠性而在其他方面提升性能。
1、提高数据发送速度。
2、节省开销。
因为,TCP协议是一种可靠的,如果数据在传输过程中出现异常,比如发送的数据包丢失,数据包失真,那么TCP协议会要求数据包重新发送。
而且TCP协议是面向连接的数据发送前客户端和服务器端要建立连接,数据发送后客户端和服务器端要断开连接。
以上特点都会影响数据包发送的速度,增加服务器和客户端的开销。
所以我们可以很容易地明白,为什么说UDP的面向无连接不可靠特性能够提速节省开销
经过上述的分析我们可以对UDP协议和TCP协议各自的优缺点都有了一个很清楚的认识,那么什么情况下使用UDP协议,什么情况下使用TCP协议呢?

请设想以下情景:
1、我们在使用QQ和好友聊天互发文字信息、图片的时候,如果你在点击发送之后,你以为信息发送出去了,可是由于网络原因,这一次信息并没有传送到好友端。如果是TCP协议那么它会要求数据包(信息)重新发送,但如果是UDP协议那么它并不会做出任何补救措施,因为它是不可靠的。
2、但是当我们在和好友进行语音通话或者视频聊天的是候,某一段语音或某一帧画面因为网络异常的原因,而失真或丢失时。如果是TCP协议它会要求数据包(信息)重新发送但是这个时候好友接收到的语音或者画面肯定是延时了,而且TCP协议的面向连接特性必定导致数据发送的缓慢。这是我们无法容忍的,而UDP协议数据传输速度很快,而且不对出差错的数据进行补救,那么虽然音频或者视频会出现少量的噪声或者数据丢失,但是保证了音频和视频的实时性,这点牺牲是可以接受的。

通过以上的场景分析,我相信大家对什么时候使用TCP协议什么时候利用UDP协议有了一个比较清晰地认识。

二、UDP协议的Java封装

Java中封装了两个类来实现UDP协议:
1、DataProgramPacket类
DataProgramPacket这个类的名字很清楚地告诉了我们,这是一个数据报包,这个包里面包含要发送的数据,因为UDP协议是面向无连接的,所以在发送时这个包里面包含了IP地址端口号来确定数据要到达的目的地址。我们在发送和接收数据包的时候都要创建DataProgramPacket类的实例来作为数据的载体。

public DataProgramPacket(byte r[],int length)
//创建一个用于接收数据报的DatagramPacket对象
//parameter:r是一个字节数组,用来缓存接收到的数据报
//parameter:length是要接收数据报的长度,length<=r.length
public DataProgramPacket(byte s[],int length,InetAddress iaddr,int port)
//创建一个用于发送数据报的DatagramPacket对象
//parameter:s是一个字节数组,用来缓存要发送的的数据报
//parameter:length是要接收数据报的长度,length<=s.length
//parameter: iaddr是数据报的目的地址
//parameter: port是数据报的目的地址端口号

2、DataProgramSocket类
我们在将数据报准备好在一个数据包即DataProgramPacket类的实例化对象中之后,还需要创建DataProgramSocket类的实例化对象利用后者将前者发送或接收。

public DataProgramSocket()throws SocketException
//创建一个自动绑定端口的socket对象,如果无法创建对象或者无法绑定到端口则抛出异常
public DataProgramSocket(int port)throws SocketException
//创建一个绑定指定端口port的socket对象,如果无法创建对象或者无法绑定到端口则抛出异常
//parameter:port 用来数据报通信的指定的端口
public DataProgramSocket(int port,InetAddress iaddr)throws SocketException
//创建一个绑定指定地址iaddr和端口port的socket对象,如果无法创建对象或者无法绑定到端口则抛出异常
//parameter:port 用来数据报通信的指定的端口
//c用来数据报通信  的指定的IP地址
public void send(DatagramPacket dp)throws IOException
//利用socket将数据包dp发送出去
//parameter:dp是要发送的数据包,里面包含了Ip地址、端口号和数据内容
public void receive(DatagramPacket dp)throws IOException
//利用socket将数据包dp接收进来
//parameter:dp是数据包存储了接收到的数据,里面包含了发送方Ip地址、端口号和数据内容

基于UDP协议的Socket编程_第1张图片

三、编程流程

我们编程时,需要编写客户端和服务器端两部分
服务端的流程:

(1) 创建一个DatagramSocket 对象
(2)进入一个循环,对客户端发来的数据进行接收,处理,响应,直到客户端数据发来数据表明传送完毕。

 1. 创建一个用于接收数据报的DatagramPacket对象。

 2. 利用DatagramSocket 类的方法receive()等待客户端的数据报包
 3. 处理接收到的数据报包

 4. 创建一个用于发送数据报的DatagramPacket对象。

 5. 利用DatagramSocket 类的方法send()等待客户端的数据报包

(3)退出循环,释放socket。

客户端流程:
(1) 创建一个DatagramSocket 对象
(2)进入一个循环,直到客户端自己要发送的数据完成。

 1. 创建一个用于发送数据报的DatagramPacket对象。

 2. 利用DatagramSocket 类的方法send()发送数据报包

 3. 创建一个用于接收数据报的DatagramPacket对象。

 4. 利用DatagramSocket 类的方法receive()等待服务器端的响应数据报包

(3)退出循环,释放socket。

可以看出,客户端先发送数据报给服务器端,服务器端对接收到的数据报内容进行处理,服务器端将处理后的信息以数据报的形式响应给客户端,客户端接收来自服务器端的响应数据报。如此循环一直到,客户端发送结束请求。

你可能感兴趣的:(网络编程,Java)