关于TCP收发包问题

max_godlike 2013-01-05 03:37:51
加精
各位大虾,我有一个很急的问题请教

问题描述:
先建立tcp连接,客户端循环调用send函数发送数据包,就假设循环两次吧。
服务端调用read一直读客户端发来的数据,结果问题来了,接收到的数据有点问题。
通过tcpdump工具抓包分析,发现有时tcp会将两次send的数据一次打包发过去,而有时则是正常一次一次打包发送,后来我想,是不是发送数据太快,于是在每次send后让其睡眠1秒,通过这种方式,发送数据正常了。

问:
tcp会整合调用多次send的数据一次发送 是否属于tcp正常行为?还是我写的程序有问题?
在线等 谢谢!
...全文
6649 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
chocolatehuhu 2014-09-03
  • 打赏
  • 举报
回复
原来是这样。
zhxingway 2014-02-11
  • 打赏
  • 举报
回复
在接收端处理一下拼帧分帧就行了。
liangxd09 2013-01-14
  • 打赏
  • 举报
回复
亲,网络最最最基本的 分包 粘包现象。能先谷歌搜搜不。偶不做网络的都知道
jackson_b_001 2013-01-11
  • 打赏
  • 举报
回复
包头+长度+内容, 包头的目的就是为了在接收端缓存里面作为切割两个数据包的分界线。比如你随便来个"ABC", 包头定义的越长,切割的错误率越低(主要是内容中也包含和包头同样的字符), 但是信道占用越大.
jackson_b_001 2013-01-11
  • 打赏
  • 举报
回复
这个是通信的最长碰到的问题。 串口通信也有这个问题。 说白了就是设计健壮的应用层协议和接收端建立缓存解析收到的数据包。 包头+长度+内容. 想直接传数据结构接收端几乎死路一条。
星火燎猿 2013-01-11
  • 打赏
  • 举报
回复
引用 31 楼 jackson_b_001 的回复:
包头+长度+内容, 包头的目的就是为了在接收端缓存里面作为切割两个数据包的分界线。比如你随便来个"ABC", 包头定义的越长,切割的错误率越低(主要是内容中也包含和包头同样的字符), 但是信道占用越大.
很有道理。
星火燎猿 2013-01-11
  • 打赏
  • 举报
回复
引用 4 楼 max_godlike 的回复:
各位都说的不错。 我昨天也看了一些博客,了解到这个是“网络粘包”问题,属于tcp正常行为。 对于“网络粘包”问题的解决方法,我也看了很多,总结有 1. 接收端自己处理包的分解 2. 增大发送延迟,例如我在每次send前睡眠1秒 3. 设置TCP头PSH (这个好像没有API接口函数) 我最想用的是第3种方法,但不知应用程序是否可以设置TCP头PSH. 通过网……
一直用第一种的飘过,感觉也不错。
ashamwolf 2013-01-11
  • 打赏
  • 举报
回复
首先要定义报文格式。 然后可以用select来读取,一次读一个字符,每读取一个字符就根据报文格式判断是否读到了完整的报文,如果读到了,就对报文做处理。
grf9527 2013-01-10
  • 打赏
  • 举报
回复
粘包,粘包,你需要在接收端建立一个大缓冲,然后你的传输协议中要求自描述信息,比如包长度。这样的话就可以拿到完整的包,又不影响下个包。
chezzy 2013-01-10
  • 打赏
  • 举报
回复
虽然我不是太懂 但是也来学习哈!电子圈
窗外蓝天 2013-01-10
  • 打赏
  • 举报
回复
以前碰到过这个问题,不知道怎么解决。学习了
  • 打赏
  • 举报
回复
1.粘包、半包 是网络编程的基本问题; 2.现阶段一般都是采用成熟的网络框架,都已经处理了此类问题;例如 java的netty框架
akb888 2013-01-10
  • 打赏
  • 举报
回复
在这里学习了
纯属为了扯淡 2013-01-10
  • 打赏
  • 举报
回复
引用 27 楼 NewHeShe 的回复:
一直搞不懂为什么会有“粘包”这个概念存在
其实是不叫粘包的。 只不过是一次recieve的调用收到了2次send数据,所以看起来就是2次send的数据“粘”一块了。 tcp是流式的传输,有可能2次send被“粘”一块接收,也有可能一次send需要2次recieve来接收的。 意思就是tcp这一层发送的数据没有明确的分隔线。需要自己定义封包的格式和解析。
NewHeShe 2013-01-10
  • 打赏
  • 举报
回复
一直搞不懂为什么会有“粘包”这个概念存在
q1659523370 2013-01-09
  • 打赏
  • 举报
回复
tcp是基于字节流的。无记录边界 你的send只是将数据暂存到tcp发送缓冲区了,由发送缓冲区经网卡传输出去是由操作系统内的相应网络驱动完成 。当然先后顺序是不会乱的。 同理你接收的时候也不可能分清是哪个send发出或是连着的。。理解流的概念。 tcp一般使用TLV编码方式 或者 文本协议
yyd01245 2013-01-09
  • 打赏
  • 举报
回复
粘包问题,楼上的方法可行的!
wjb_yd 2013-01-09
  • 打赏
  • 举报
回复
TCP是数据流的嘛,自己定义好应用层协议,每次按协议来取出当前包的长度,再recv实际数据传递给逻辑层。
不要做咸鱼 2013-01-09
  • 打赏
  • 举报
回复
最好的解决方法是封包,然后再拆包。。。
纯属为了扯淡 2013-01-09
  • 打赏
  • 举报
回复
做过tcp传输的,没有不知道这个粘包问题的。 最常见的解决办法是把消息包处理成如下格式: 消息类型+消息头部+消息体长度。其中消息类型和消息头部固定字节数。 这样可以适应任何长度的数据包传输。 发送和接收端需要根据这样的格式进行解码
加载更多回复(17)

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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