linux TCP发送数据卡在协议栈,发不出去

lzwml 2016-01-12 08:42:09
具体问题描述在这
《linux TCP服务器连接时发不出数据,断开瞬间发送全部数据》

http://bbs.eeworld.com.cn/thread-480763-1-1.html

服务器和两个客户端连接,采用epoll非阻塞方式,客户端分别发送心跳包(6s一次),服务器发送心跳回应,接收在一个线程,人为操作服务器,每个1S查询一次客户端业务情况,发送在另一个线程,此线程与接收线程未作互斥同步(Socket有同时写的可能)

所以服务器的两个线程大约每隔6一次数据冲突。(这是诱因)
抓包发现的确出现有一定概率的数据冲突。


冲突后,接着服务器关闭1S的查询业务,网络上只心跳包和心跳回应包。
代码上看:
每次客户端发心跳包后,服务器返回心跳回应都成功,这两种数据包都不大,都是40byte
问题是客户端收不到任何数据(这是我关注的问题)
抓包显示此时只有服务器端的TCP协议栈返回受到数据的ACK应答, 数据内容并不包含心跳应答???


过了1min后客户端断开连接
抓包显示10次供400byte的心跳应答一次性发完


同事对最后一次发送的分析是:
TCP断开会有半连接状态,主动断开放问对方是否有数据要发,有就一次性发送。
...全文
772 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
MenglongWoo 2016-01-14
  • 打赏
  • 举报
回复
太不注意了
lzwml 2016-01-13
  • 打赏
  • 举报
回复
估计找到问题了,两个client冲突,其中一个client的MAC地址在跳动导致数据被交换机转发错误。 client是RT-Thread别人写的读取MAC模块 现在不用对方的MAC代码,自己写死MAC,查看情况
lzwml 2016-01-13
  • 打赏
  • 举报
回复
下面是拓扑图

我怀疑上面的两次数据错误是因为交换机数据转发错误,
因为在抓包端【偶尔】能收到192.168.1.254(服务器)发往192.168.0.6(另一台客户端)的流量

那么同样两次错误包也有可能将本该发往192.168.0.20(关注的客户端)的数据发往192.168.0.6(另一台客户端),
【并且】这之后还发生了什么????导致服务器不重发该数据包!!!!
lzwml 2016-01-13
  • 打赏
  • 举报
回复
引用 1 楼 pcboyxhy 的回复:
心跳包一般需要设置TCP_NODELAY

找到点线索,可能是TCP包错位【没有重传】导致
下面的图片是两组数据包处理重传的情况,
其中第一种处理了重传,另一个没有

54号数据:序列号是117,下一个期望序列号(121)

66号数据:错误(TCP Previous segment not capture)表示这个包(273)之前的包(121)没有收到,序列号错误。
121的数据包没有发送成功(该包可能路由走错了,待会发路由拓扑图),序列号变成【273】不是(121)

同时67号数据,纠正错误(重传TCP Retransmission)

这样,通信一切正常

紧接着7S后又出现一次(TCP Previous segment not capture)错误
93号数据:序列号421,下一个期望序列号(也是421,因为这个包是个【纯ACK】包)
104号数据:(TCP Previous segment not capture)错误,序列号473,不是431

pcboyxhy 2016-01-12
  • 打赏
  • 举报
回复
心跳包一般需要设置TCP_NODELAY

18,361

社区成员

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

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