TCP和UDP的"保护消息边界”

转自:http://blog.csdn.net/zhangxinrun/article/details/6721427

在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。
       对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了

保护消息边界和流

那么什么是保护消息边界和流呢?

保护消息边界,就是指传输协议把数据当作一条独立的消息在网上 
传输,接收端只能接收独立的消息.也就是说存在保护消息边界,接收 
端一次只能接收发送端发出的一个数据包. 
       而面向流则是指无保护消息保护边界的,如果发送端连续发送数据, 
接收端有可能在一次接收动作中,会接收两个或者更多的数据包.

我们举个例子来说,例如,我们连续发送三个数据包,大小分别是2k, 
4k , 8k,这三个数据包,都已经到达了接收端的网络堆栈中,如果使 
UDP协议,不管我们使用多大的接收缓冲区去接收数据,我们必须有 
三次接收动作,才能够把所有的数据包接收完.而使用TCP协议,我们 
只要把接收的缓冲区大小设置在14k以上,我们就能够一次把所有的 
数据包接收下来.只需要有一次接收动作.

这就是因为UDP协议的保护消息边界使得每一个消息都是独立的.而 
流传输,却把数据当作一串数据流,他不认为数据是一个一个的消息.

所以有很多人在使用tcp协议通讯的时候,并不清楚tcp是基于流的 
传输,当连续发送数据的时候,他们时常会认识tcp会丢包.其实不然, 
因为当他们使用的缓冲区足够大时,他们有可能会一次接收到两个甚 
至更多的数据包,而很多人往往会忽视这一点,只解析检查了第一个 
数据包,而已经接收的其他数据包却被忽略了.所以大家如果要作这 
类的网络编程的时候,必须要注意这一点.

结论:
     根据以上所说,可以这样理解,TCP为了保证可靠传输,尽量减少额外
开销(每次发包都要验证),因此采用了流式传输,面向流的传输,
相对于面向消息的传输,可以减少发送包的数量。从而减少了额外开
销。但是,对于数据传输频繁的程序来讲,使用TCP可能会容易粘包。
当然,对接收端的程序来讲,如果机器负荷很重,也会在接收缓冲里
粘包。这样,就需要接收端额外拆包,增加了工作量。因此,这个特
别适合的是数据要求可靠传输,但是不需要太频繁传输的场合(
两次操作间隔100ms,具体是由TCP等待发送间隔决定的,取决于内核
中的socket的写法)

而UDP,由于面向的是消息传输,它把所有接收到的消息都挂接到缓冲
区的接受队列中,因此,它对于数据的提取分离就更加方便,但是,
它没有粘包机制,因此,当发送数据量较小的时候,就会发生数据包
有效载荷较小的情况,也会增加多次发送的系统发送开销(系统调用,
写硬件等)和接收开销。因此,应该最好设置一个比较合适的数据包
的包长,来进行UDP数据的发送。(UDP最大载荷为1472,因此最好能
每次传输接近这个数的数据量,这特别适合于视频,音频等大块数据
的发送,同时,通过减少握手来保证流媒体的实时性)

时间: 2024-10-12 22:49:43

TCP和UDP的"保护消息边界”的相关文章

有关TCP和UDP 粘包 消息保护边界

http://www.cnblogs.com/lancidie/archive/2013/10/28/3392428.html 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的 socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一 个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机

【转】关于TCP和UDP协议消息保护边界的介绍

在 socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的 socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制.对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接

UDP TCP 消息边界

先明确一个问题,如果定义了一个数据结构,大小是,比方说 32 个字节,然后 UDP 客户端连续向服务端发了两个包.现在假设这两个包都已经到达了服务器,那么服务端调用 recvfrom 来接收数据,并且缓冲区开得远大于 64,例如,开了 1024 个字节,那么,服务端的 recvfrom 函数是会一次收到两个数据包呢,还是只能收到一个. 答案是只能收到一个. 来看代码: struct.h #ifndef STRUCT_H #define STRUCT_H typedef struct _UDP_M

介绍开源的.net通信框架NetworkComms框架之四 消息边界

原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是:Apache License v2 开源地址是:https://github.com/MarcFletcher/NetworkComms.Net 首先,使用TCP通信的时候存在消息边界的问题,也就是如何处理粘包问题,networkcomms 框架本身已经对这个问题有内置的解决方案,我们在使用框架时

网络 套接字编程 TCP、UDP

网络是大端 发数据从低地址发, 先发的是 高位的数据. 收数据从高位收,先收到的数据存放到低地址. TCP 是 流式的 所用套接字也是流式的 文件描述符 socket 是 IP 加 端口号 用到的函数:         int socket(int domain, int type, int protocol);        int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);        #include <s

【转】TCP协议的无消息边界问题

http://www.cnblogs.com/eping/archive/2009/12/12/1622579.html 使用TCP协议编写应用程序时,需要考虑一个问题:TCP协议是无消息边界的,即不能保证来自单个Send方法的数据能被单个Receive方法读取. eg: 第一次发送:abcdefg   第二次发送:123456         接收方接收数据时,可能会出现以下情况: 第一次接收:abcdefg123456   也可能出现:第一次接收:abc 第二次接收:efg12 第三次接收:

TCP和UDP的区别

TCP和UDP的区别 TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! TCP/IP协议是一个协议簇.里面包括很多协议的.UDP只是其中的一个.之所以命名为TCP/IP协议,因为TCP,IP协议是两个很重要的协议,就用他两命名了. TCP/IP协议集包括应用层,传输层,网络层,网络访问层. 其中应用层包括: 超文本传输协议(HTTP):万维网的基本协议

理解TCP和UDP协议

目录 TCP 协议 UDP协议 TCP和UDP的区别 TCP和UDP的使用场景 一 TCP协议 1.TCP的头部格式 理解TCP协议,首要的就是TCP协议的头部格式 ·        Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号:用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接: ·        Sequence Number:用来标识从T

[转]TCP、UDP区别

转自:http://zhangjiangxing-gmail-com.iteye.com/blog/646880 TCP协议与UDP协议的区别    首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信!TCP/IP协议是一个协议簇.里面包括很多协议的.UDP只是其中的一个.之所以命名为TCP/IP协议,因为TCP,IP协议是两个很重要的协议,就用他两命名了.TCP/IP协议集包括应用层