TCP所谓的数据流方式如何理解?

askppp 2005-02-16 09:18:26
比如我分开发送了两个数据包,内容分别是aaa bbb

那在我接受方套接字缓冲里就是aaabbb

如果这时我要接受4个字节,就会收到aaab,而无法知道他们是不同数据包的数据?

这是不是所谓的“粘包”?
...全文
570 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
jim801716 2005-02-20
  • 打赏
  • 举报
回复
但在我实际写程序测试时候,即使是1个字节的tcp数据也被立即发送出去了,我没有更改默认设置。
--------------------------------------------------------------------------------------

还有时间的限制,具体要看协议算法的实现
askppp 2005-02-19
  • 打赏
  • 举报
回复
谢谢各位,还有一个问题:

===========================引用上面===================================

“TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。”

=======================================================================


但在我实际写程序测试时候,即使是1个字节的tcp数据也被立即发送出去了,我没有更改默认设置。

JJONY 2005-02-18
  • 打赏
  • 举报
回复
TCP协议 常说的是“流式”通讯,其实用“流式”来形容TCP的数据传输我觉得非常恰当的。
其中暗示了接收方接收数据像流水一样。可以想像连续流动的水它有几段啊?

可想而知OS从SOCKET那边给我们的是一条“流动”的数据,这条数据是没有边界的,也就是说没有“包”的概念,反正就是一堆数据,我们收完数据OS的任务就完成了,所以就不要想什么“粘包”问题了。然后,我们要考虑的就是这条“流动”数据的接收方式。接收方式就是所采用的SOCKET I/O模型,总的来说就是调用recv函数来一段-段地去接收这条数据流。而这里的“一段”的大小不是代表“包”的大小,只能由recv返回的长度决定,如果OS 内部BUF的数据大小>=我们给recv的buf,那就返回recv的BUF大小,否则就是OS BUF大小这个大小往往<>发送方调用一次SEND的大小,所以就会出现所谓“分包”的情况。

至于这种“粘包”与“分包”造成写程序的不爽(自己解包与组包)是必然的,还是老老实实的去做吧。aabb的情况经常会出现
sealor109 2005-02-18
  • 打赏
  • 举报
回复
http://www.xbxb.net/look.asp?user=sealor109
xjtuzhw 2005-02-18
  • 打赏
  • 举报
回复
发送和接收的消息包中已经包含了关于这条数据的所有信息,如数据长度(太大会分段传输),格式(文件,信息等)...
收到的消息在缓冲区应该有一个明显的分隔,但是在CPU无法及时处理数据的时候会出现"粘包"
loucai 2005-02-18
  • 打赏
  • 举报
回复
学习
loucai 2005-02-18
  • 打赏
  • 举报
回复
学习
hjunxu 2005-02-18
  • 打赏
  • 举报
回复
楼上说的没有错,TCP本来就没有“包”这个概念。谈不上粘不粘。

================================
在接受方接收了两条数据包后,缓冲区里是不是只有aaabbb,当中没有什么间隔标志,单从缓冲区内容无法知道他们是来自同一数据包还是不同数据包的数据,是不是这样?
=============================
楼主的这个理解是对的。
test422 2005-02-17
  • 打赏
  • 举报
回复
哈哈,你的理解本来就是很正确地.
allenq 2005-02-17
  • 打赏
  • 举报
回复
采用在每个数据包前加4个字节的附加包文: 标示长度
如发送方为 "aaa"时, 实际发送的为"0003aaa", 这样接收方根据先前接收的4个字节"0003"转换后再次接收3个字节的长度! 工程上这样处理可以有效解决粘包的问题了.
呵呵, 只是提个解决方案而已.
wqs6 2005-02-17
  • 打赏
  • 举报
回复
学习
askppp 2005-02-17
  • 打赏
  • 举报
回复
我是楼主
=================

楼上前三位误会我的意思了,我不是问粘包的解决方案。

我问的是:

发送方发了两条tcp数据包,内容是aaa和bbb

在接受方接收了两条数据包后,缓冲区里是不是只有aaabbb,当中没有什么间隔标志,单从缓冲区内容无法知道他们是来自同一数据包还是不同数据包的数据,是不是这样?


plutowolf 2005-02-17
  • 打赏
  • 举报
回复
前不久kingzai(stevenzhu)贴过
二、粘包问题分析与对策
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据(图1所示)。
粘包情况有两种,一种是粘在一起的包都是完整的数据包(图1、图2所示),另一种情况是粘在一起的包有不完整的包(图3所示),此处假设用户接收缓冲区长度为m个字节。
不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。
在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结构数据的粘包问题时,分包算法就比较复杂。特别是如图3所示的粘包情况,由于一包数据内容被分在了两个连续的接收包中,处理起来难度较大。实际工程应用中应尽量避免出现粘包现象。
为了避免粘包现象,可采取以下几种措施。一是对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push, TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;二是对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;三是由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。
以上提到的三种措施,都有其不足之处。第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包。第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。
一种比较周全的对策是:接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。对这种方法我们进行了实验,证明是高效可行的。
xjtuzhw 2005-02-17
  • 打赏
  • 举报
回复
你说的现象不属于 "粘包"的范畴,"粘包" 是属于网络不够健全的反应,是前后数据接收过程的处理失误,在接收的缓冲区没有正确的从每个信息头提取正确的信息
你说的方法是属于 自定义的取信方式,这与"粘包"无关

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧