当前位置: 技术问答>linux和unix
深入了解Linux系统TCP通信的高手请帮帮忙:Linux通信问题.分不够再加
来源: 互联网 发布时间:2015-11-07
本文导语: 我做一个通信中间件.客户端程序使用TCP/IP连接和它在一台计算机上的这个中间件.然后在通过这个中间件与另一台计算机上的中间件进行通信. CLIENT APP --->(TCP/IP)---->中间件1--->(TCP/IP)---->中间件2--->(TCP/IP)---->SERVER APP ...
我做一个通信中间件.客户端程序使用TCP/IP连接和它在一台计算机上的这个中间件.然后在通过这个中间件与另一台计算机上的中间件进行通信.
CLIENT APP --->(TCP/IP)---->中间件1--->(TCP/IP)---->中间件2--->(TCP/IP)---->SERVER APP
中间件1与CLIENT APP在一台计算机上.中间件2与SERVER APP在另一台计算机上.中间件是使用了多线程的.
我现在连续12次向中间件1发送数据.中间件1每收到一个数据我都先向中间件2发送.然后再向CLIENT APP返回应答信息,然后CLIENT APP再发第二次数据.这样反复12次.但现在有一个奇怪的问题.就是中间件1中的线程虽然是先向中间件2发送数据.但实质上没有发送出去的.可能是存放在了TCP的滑动窗口里面了.直到等到CLIENT APP的连续12个数据都向中间件1发送完毕后中间件1才向中间件2把滑动窗口里存储的数据一齐发送到中间件2.从中间件1发送最后一条数据开始记时到中间件2第一次收到数据截止花了20毫秒.正好是一个CPU时间片的时间.我也使用了TCP_NODELAY.但好象没有什么效果.
中间件1先向中间件2发送数据后,再向CLIENT APP发送应答信息.这时应该中间件2先收到信息,然后CLIENT APP再收到应答信息.即使是CLIENT APP先收到信息.也应该是中间件2与CLIENT APP交替收到信息.不会等到CLIENT APP都接收完毕中间件2那边才开始收.我即使使用不同的线程分别向两边发送也是一样的结果.是不是有什么TCP的属性没有设置?请高手指点.
CLIENT APP --->(TCP/IP)---->中间件1--->(TCP/IP)---->中间件2--->(TCP/IP)---->SERVER APP
中间件1与CLIENT APP在一台计算机上.中间件2与SERVER APP在另一台计算机上.中间件是使用了多线程的.
我现在连续12次向中间件1发送数据.中间件1每收到一个数据我都先向中间件2发送.然后再向CLIENT APP返回应答信息,然后CLIENT APP再发第二次数据.这样反复12次.但现在有一个奇怪的问题.就是中间件1中的线程虽然是先向中间件2发送数据.但实质上没有发送出去的.可能是存放在了TCP的滑动窗口里面了.直到等到CLIENT APP的连续12个数据都向中间件1发送完毕后中间件1才向中间件2把滑动窗口里存储的数据一齐发送到中间件2.从中间件1发送最后一条数据开始记时到中间件2第一次收到数据截止花了20毫秒.正好是一个CPU时间片的时间.我也使用了TCP_NODELAY.但好象没有什么效果.
中间件1先向中间件2发送数据后,再向CLIENT APP发送应答信息.这时应该中间件2先收到信息,然后CLIENT APP再收到应答信息.即使是CLIENT APP先收到信息.也应该是中间件2与CLIENT APP交替收到信息.不会等到CLIENT APP都接收完毕中间件2那边才开始收.我即使使用不同的线程分别向两边发送也是一样的结果.是不是有什么TCP的属性没有设置?请高手指点.
|
用select来接收,还是阻塞在read?基本的代码结构能否写一下?
|
根据我片面的理解。TCP本来就是基于流的,只是在网络层折成包,它有发送缓冲区和接收缓冲区,一般情况下,只有发送缓冲区到达一定的量或超过预设的时间才开始发包,接收同样,否则的话,如果一个包只发几个字节,网络层和应用层每收一个包就通知一次不忙死(本来TCP协议在应用层就没有包的概念)。
如果你一定要强调应答的时间。用UDP比用TCP会好得多。因为UDP是基本包的。
如果你一定要强调应答的时间。用UDP比用TCP会好得多。因为UDP是基本包的。
|
这应该是典型的TCP粘包问题, CLIENT APP --->(TCP/IP)---->中间件1 之间的通讯是很快的, 所以中间件2收到的数据也很快, 所以你的SERVER并不是你的数据一到达就接收一次, 当他开始接收数据是, 中间件1的数据已经发送了很多次了, 所以就一次接收完了。 就是你设置了TCP的相关属性, 可能会好些, 但不能解决根本的问题! 如果你的每次数据都要分开接收, 建议你标识你每次发送的数据, 在SERVER端收到后解析, 就是你一次接收到12次的数据, 也没有问题的
|
一定是调度问题吗,是不是TCP滑动窗口的问题,换个思路测试一下,也许可以发现问题。
|
中间件是你自己做的吗?如果是3rd party的产品,估计中间件的实现上又缓冲的嫌疑(比如说缓冲到一定大小或延迟一定时间后再发送)。至于上面说的“TCP粘包”或OS 调度应该与你遇到的问题无关。