TCP和UDP的保护消息边界机制
在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,因此最好能每次传输接近这个数的数据量,这特别适合于视频,音频等大块数据的发送,同时,通过减少握手来保证流媒体的实时性)
TCP和UDP的保护消息边界机制的更多相关文章
- TCP和UDP的"保护消息边界" (经典)
在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有 ...
- TCP和UDP的"保护消息边界”
转自:http://blog.csdn.net/zhangxinrun/article/details/6721427 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP ...
- 有关TCP和UDP 粘包 消息保护边界
http://www.cnblogs.com/lancidie/archive/2013/10/28/3392428.html 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因 ...
- 【转】关于TCP和UDP协议消息保护边界的介绍
在 socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的 socket,因此,发送端为了将多个发往接收端的包, ...
- UDP TCP 消息边界
先明确一个问题,如果定义了一个数据结构,大小是,比方说 32 个字节,然后 UDP 客户端连续向服务端发了两个包.现在假设这两个包都已经到达了服务器,那么服务端调用 recvfrom 来接收数据,并且 ...
- 介绍开源的.net通信框架NetworkComms框架之四 消息边界
原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是 ...
- 基于tcp的应用层消息边界如何定义
聊聊基于tcp的应用层消息边界如何定义 背景 2018年笔者有幸接触一个项目要用到长连接实现云端到设备端消息推送,所以借机了解过相关的内容,最终是通过rabbitmq+mqtt实现了相关功能,同时在心 ...
- 【转】TCP协议的无消息边界问题
http://www.cnblogs.com/eping/archive/2009/12/12/1622579.html 使用TCP协议编写应用程序时,需要考虑一个问题:TCP协议是无消息边界的, ...
- Mina、Netty、Twisted一起学(二):TCP消息边界问题及按行分割消息
在TCP连接开始到结束连接,之间可能会多次传输数据,也就是服务器和客户端之间可能会在连接过程中互相传输多条消息.理想状况是一方每发送一条消息,另一方就立即接收到一条,也就是一次write对应一次rea ...
随机推荐
- JS案例之1——pager 分页
学习JS大半年之久,第一次自己尝试写一些小插件,写法参考网上某位牛人写代码的思路. 此处代码写的是静态分页.如果需动态分页,还可以修改下.第一次写,还有很多地方可以优化.希望各位大牛踊跃拍砖. 预览图 ...
- 使用Windows Live Writer发布日志
前言 Windows Live Writer是非常不错的一个日志发布工具,支持本地写文章,然后通过点击一个按钮就发布到网站上,如果借助插件,还可以同时发布到多个博客网站,功能非常强大,很多博友认识她之 ...
- 系统级I/O
Unix I/O 输入操作是从I/O设备拷贝数据到主存,而输出操作是从主存拷贝数据到I/O设备. 一个文件就是一个字节序列. 所有的I/O设备,如网络.磁盘.和终端,都被模型化为文件,而所有的输入和输 ...
- 创建Spring容器
对于使用Spring的web应用,无须手动创建Spring容器,而是通过配置文件,声明式的创建Spring容器.在Web应用中,创建Spring容器有如下两种方式:1.直接在web.xml文件中配置: ...
- Jenkins进阶系列之——03parameterized-trigger插件
说明:这个插件可以根据已经完成构建的结果,触发新Job或者传递参数. 官方说明:Parameterized Trigger Plugin 安装步骤: 系统管理→管理插件→可选插件→Build Trig ...
- Jenkins进阶系列之——08Jenkins纳入版本控制
2014-07-25:更新shell脚本 2014-06-05:更新shell脚本 2014-01-09:更新shell脚本,修改Jenkins文件删除后不能自动从版本控制删除的bug 是不是有过这种 ...
- C#基础之lock
1.lock的本质 实现线程同步的第一种方式是我们经常使用的lock关键字,它将包围的语句块标记为临界区,这样一次只有一个线程进入临界区并执行代码.下面第一段的几行代码是关于lock关键字的使用方式, ...
- css圆角矩形及去掉空格属性
css圆角矩形 -webkit-border-radius:5px; -moz-border-radius:5px; border-radius:5px; 去掉空格 white-space:nowra ...
- [bzoj1296][SCOI2009]粉刷匠(泛化背包)
http://www.lydsy.com:808/JudgeOnline/problem.php?id=1296 分析: 首先预处理出每一行的g[0..T]表示这一行刷0..T次,最多得到的正确格子数 ...
- javascript与服务器1
A. 通过在客户端设置Cookie,然后在服务器端读取它. 关于Cookie只说明一点, 它是存储在客户端机器上的一小块信息, 可以有客户端程序或服务器程序创建,并通过http传递.常用于跟踪用户在客 ...