TCP粘包问题

哮浪 2014-01-13 07:36:57
TCP出现粘包问题,有好几种解决方法,比如:tcp push设置,结束符,固定长度等,但请问其中的tcp push设置是怎么实现的?
...全文
3007 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
MrBai_2511 2015-12-11
  • 打赏
  • 举报
回复
我现在也遇到这样的情况了 我的协议里面有数据大小 但是还是出现粘包的现象。 typedef struct _cmd_t //控制指令 { int cmd; int buf_len; char buf[MAXDATASIZE]; }cmd_t;
聚义舔刀 2014-12-18
  • 打赏
  • 举报
回复
引用 18 楼 wumn29 的回复:
“粘包”这个词汇本身有问题, TCP是流协议, 传输的是流不是报文, 什么是流, 流就是不需要管它的大小, 我一次性倒一桶水进缸里, 喝的时候是一次性全喝光吗? 这个词读起来也怪怪的, 我打lianbao打不出来, 打zhanbao打出来, 莫非真的读zhanbao?
哈哈哈
yichudu 2014-12-18
  • 打赏
  • 举报
回复
TCP粘包问题。 TCP提供的是可靠的字节流服务。假设TCP接收方是B,发送方是A。 理想情况下,B每次read的都是A每次write的内容,但事实不是这样的。 会出现A第一次发送(write)qwer这个字节流,第二次发送tyui;而B第一次读到(read)的是qwe,第二次read的是rt,第三次read的是yui这种情况。 为什么呢? 应用层的数据交给TCP,会被分割再包装成TCP报文,再加上下面IP层的缓冲区处理、网络拥塞等状况,就会发生上面的情况。 应对方法 应用层发送“你好”,假设对应的字节数组是[1,2,3,4],那么处理后交给TCP的是 [0,4,1,2,3,4],前两个byte固定放本次传输数据量的大小。TCP接收端再写一个相应的函数,依据长度提取字节就可以啦。
firefly3233 2014-09-05
  • 打赏
  • 举报
回复
最近也遇到了这个问题,粘包了,只要粘在一起的包都是完整的包,还好处理,因为你有协议,但粘包中又有断包,就比较难处理了。我遇到了一个协议,包头没有指定长度,但后面有些判断数据长度的代码。所以发现不完整包,就一直循环直到包完整,只要都是完整的包,粘在一起也没关系,自己根据协议循环处理就行了。 BYTE pBuf[8192]; int nLen; nLen = recv(sock, (char*)pBuf, sizeof(pBuf), 0); m_pBuf = (BYTE*)realloc(m_pBuf, m_nLen + nLen); memcpy(m_pBuf + m_nLen, pBuf, nLen); m_nLen += nLen; if (!CheckPacket(m_pBuf, m_nLen))//如果包不完整,则返回 return; DecordPacket(m_pBuf, m_nLen);//解包,不怕粘包,因为用规定好的协议循环处理
夫人的泡泡鱼 2014-09-01
  • 打赏
  • 举报
回复
这就是TCP的底层打包做导致的,我使用的通信协议 报文头 报文类型 报文长度 报文参数 在接收端根据判断是否是一个报文的开始,如果收到了报文长度则判断现在的数据是否符合长度要求,如果没有收到长度,先把接受数据保存,继续接收,直到接收到了报文长度,根据这个长度可以处理接收的数据,取得完整一条报文后,就可以对其进行处理,而后接收吓一条数据
dvlinker 2014-08-19
  • 打赏
  • 举报
回复
1、最好的方式就是添加包头,包头的长度固定,至于包中携带的数据长度可以写到包头中 2、接收端先接收固定长度的包头,包中的数据长度则由包头中给出,接着接收指定长度的数据
「已注销」 2014-08-19
  • 打赏
  • 举报
回复
出现粘包的情况如下: 比如你一次性接收固定 BUF 大小的数据(比如1024字节) 尤其是在处理 iocp 接收数据的时候, 发送端的一个数据包可能没有1024字节大小,比方说发送聊天内容,一个聊天内容即一个数据包,1024字节就可能包含很多个 数据包,第二次接收固定BUF大小的数据的时候,就可能会出现了粘包,半包问题! ==》 这种情况就必须要做粘包,半包处理了!! 该固定BUF缓存最后一个数据包可能结构如下: 1. 只包含了部分包头,余下包头及全部包体在下一次接收的固定BUF缓存中首部 2.刚好包含了完整包头,包体在下一次接收的固定BUF缓存中首部 3. 包含了全部包头及部分包体,余下包体在下一次接收的固定BUF缓存中首部 (让以上粘包,半包问题出现很容易,服务器在命令行模式下,按住cmd.exe滚动条,客户端依然在不断的发送数据) 避免粘包问题的方法思路其实很简单: 接收端线性接收数据,保证先读包头(sizeof( packet_header_t)) 大小的数据,并验证校验和,然后再根据包头里包含的 包体数据大小,接收指定长度的数据, 以此接收方式循环.....
翅膀又硬了 2014-05-29
  • 打赏
  • 举报
回复
引用 20 楼 aaronjzhang_ 的回复:
今天面试就被问到这个问题,觉得好奇怪!首先TCP根本就没有包的概念,何来黏包一说!使用TCP协议都要设计应用层的协议,应用层协议就需要处理每个消息的的序列化和反序列化,根本就不存在黏包一说
你面试这样说,估计不是什么好事儿。人家怎么问你,你就按照人家的思路,好好答就是了。
worldy 2014-05-29
  • 打赏
  • 举报
回复
发送方如果目的ip/端口相同,可能会组合若干包一起发送;接收方可能会来自同一个ip?端口的若干包提交给sock。这是普遍的,必须使用自定义的协议进行处理
紫枫无涯1 2014-05-28
  • 打赏
  • 举报
回复
自定义应用层协议 自己解包就可以了
aaronjzhang_ 2014-05-26
  • 打赏
  • 举报
回复
今天面试就被问到这个问题,觉得好奇怪!首先TCP根本就没有包的概念,何来黏包一说!使用TCP协议都要设计应用层的协议,应用层协议就需要处理每个消息的的序列化和反序列化,根本就不存在黏包一说
  • 打赏
  • 举报
回复
引用 18 楼 wumn29 的回复:
“粘包”这个词汇本身有问题, TCP是流协议, 传输的是流不是报文, 什么是流, 流就是不需要管它的大小, 我一次性倒一桶水进缸里, 喝的时候是一次性全喝光吗? 这个词读起来也怪怪的, 我打lianbao打不出来, 打zhanbao打出来, 莫非真的读zhanbao?
那个字念nian或zhan,不会念lian的
wumn29 2014-01-27
  • 打赏
  • 举报
回复
“粘包”这个词汇本身有问题, TCP是流协议, 传输的是流不是报文, 什么是流, 流就是不需要管它的大小, 我一次性倒一桶水进缸里, 喝的时候是一次性全喝光吗? 这个词读起来也怪怪的, 我打lianbao打不出来, 打zhanbao打出来, 莫非真的读zhanbao?
weiran911 2014-01-25
  • 打赏
  • 举报
回复
靠谱的做法还是接收端自己确定边界
danscort2000 2014-01-24
  • 打赏
  • 举报
回复
tcp是流,你如果把它看做包,迟早出问题
哮浪 2014-01-20
  • 打赏
  • 举报
回复
引用 3 楼 KaleoVon 的回复:
"如果待发送的数据会清空发送缓存,那么TCP栈就会自动为此包设置PUSH标志。实际上现在的TCP协议栈基本上都可以自行处理这个问题,而不是交给应用层处理。" TCP是基于流的,实际应用中很难界定缓冲区中包与包的界限。现在主流且有效的做法就是加包头,不要考虑这些不实用的方式了。
嗯 是这方法不实际 但是只是想知道如何实现 呵呵
哮浪 2014-01-20
  • 打赏
  • 举报
回复
引用 8 楼 my3439955 的回复:
tcp粘包问题靠push是无法解决的了的 push的作用:对方的包源源不断的发过来,接收方的内核未必收到一个包就通知上层一次,如果包足够频繁,它可以积累一些一块通知上层。push标识就是告诉接收者,这个包尽快上报,最好不要缓存了。接收方看到这个标识,会酌情处理(看协议实现者的心情了)。 因此,所有的包都加了push,也不能保证不会粘包。 总结,写程序时,即便99.999%的情况下不会出现粘包和裂包,也要兼容粘包和裂包的处理,即时刻做着粘包和裂包出现的准备。
谢谢!至少让我知道push的作用!
erben 2014-01-14
  • 打赏
  • 举报
回复
另外不懂TCP PUSH
erben 2014-01-14
  • 打赏
  • 举报
回复
TCP实质是可靠传输字节流,不保证流的连续传输,所谓沾包只是应用层的不成熟协议的产物,使用带包头的协议,就无所谓沾不沾包
Eleven 2014-01-14
  • 打赏
  • 举报
回复
自定义协议,定义包头数据~
加载更多回复(10)

18,356

社区成员

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

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