面向报文(UDP)和面向字节流(TCP)的区别

网络 网络管理
面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。

面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会是IP太小。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。

面向字节流的话,虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流。TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。

下图是TCP和UDP协议的一些应用。

 

 

下图是TCP和UDP协议的比较。

 

 

这里再详细说一下面向连接和面向无连接的区别:

面向连接举例:两个人之间通过电话进行通信;

面向无连接举例:邮政服务,用户把信函放在邮件中期待邮政处理流程来传递邮政包裹。显然,不可达代表不可靠。

从程序实现的角度来看,可以用下图来进行描述。

 

 

从上图也能清晰的看出,TCP通信需要服务器端侦听listen、接收客户端连接请求accept,等待客户端connect建立连接后才能进行数据包的收发(recv/send)工作。而UDP则服务器和客户端的概念不明显,服务器端即接收端需要绑定端口,等待客户端的数据的到来。后续便可以进行数据的收发(recvfrom/sendto)工作。

在前面讲解UDP时,提到了UDP保留了报文的边界,下面我们来谈谈TCP和UDP中报文的边界问题。在默认的阻塞模式下,TCP无边界,UDP有边界。

● 对于TCP协议,客户端连续发送数据,只要服务端的这个函数的缓冲区足够大,会一次性接收过来,即客户端是分好几次发过来,是有边界的,而服务端却一次性接收过来,所以证明是无边界的;

● 而对于UDP协议,客户端连续发送数据,即使服务端的这个函数的缓冲区足够大,也只会一次一次的接收,发送多少次接收多少次,即客户端分几次发送过来,服务端就必须按几次接收,从而证明,这种UDP的通讯模式是有边界的。

TCP无边界,造成对采用TCP协议发送的数据进行接收比较麻烦,在接收的时候易出现粘包,即发送方发送的若干包数据到接收方接收时粘成一包。由于TCP是流协议,对于一个socket的包,如发送 10AAAAABBBBB两次,由于网络原因***次又分成两次发送, 10AAAAAB和BBBB,如果接包的时候先读取10(包长度)再读入后续数据,当接收得快,发送的慢时,就会出现先接收了 10AAAAAB,会解释错误 ,再接到BBBB10AAAAABBBBB,也解释错误的情况。这就是TCP的粘包。

在网络传输应用中,通常需要在网络协议之上再自定义一个协议封装一下,简单做法就是在要发送的数据前面再加一个自定义的包头,包头中可以包含数据长度和其它一些信息,接收的时候先收包头,再根据包头中描述的数据长度来接收后面的数据。详细做法是:先接收包头,在包头里指定包体长度来接收。设置包头包尾的检查位( 比如以0xAA开头,0xCC结束来检查一个包是否完整)。对于TCP来说:

1)不存在丢包,错包,所以不会出现数据出错 ;

2)如果包头检测错误,即为非法或者请求,直接重置即可。

为了避免粘包现象,可采取以下几种措施。

一、对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;

二、对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;

三、由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。

责任编辑:林琳 来源: CSDN
相关推荐

2013-10-17 10:35:06

TCP字节流UDP数据报

2022-07-30 23:41:53

面向过程面向对象面向协议编程

2013-07-30 09:42:41

实现编程接口编程对象编程

2015-03-20 09:54:44

网络编程面向连接无连接

2010-07-09 11:12:09

UDP协议

2009-07-02 13:25:00

消除实现继承面向接口编程Java

2013-05-27 10:48:16

TCPUDP传输协议

2009-06-22 11:27:59

反向控制原理面向切面编程Spring

2023-02-22 18:06:35

函数javascript面向对象编程

2023-10-24 15:22:09

TCPUDP

2010-07-07 10:45:22

TCP UDP协议

2015-10-09 10:49:06

AWS数据库迁移RDS

2017-09-25 21:27:07

TCP协议数据链

2021-05-18 12:27:40

TCP控制协议

2021-01-29 06:11:08

TCP通信三次握手

2019-05-28 10:32:29

TCPUDP SYN

2019-09-06 09:05:25

TCP协议通信

2013-06-27 14:41:40

TCP端口TCP

2021-07-03 17:47:25

TCP控制协议

2023-01-10 09:38:09

面向对象系统
点赞
收藏

51CTO技术栈公众号