我有一个不寻常的情况:我在嵌入式情况下使用Linux系统(英特尔盒子,当前使用2.6.20内核。),它必须与具有部分损坏的TCP实现的嵌入式系统通信。就像我现在所知,他们希望我们的每条消息都来自一个单独的以太网帧!当消息在以太网帧中分离时,它们似乎有问题。
我们在设备的本地网络上,我们之间没有路由器(只是一个交换机)。
当然,我们试图强迫他们修复他们的系统,但这可能不会最终成为可行。
我已经在我的套接字上设置了TCP_NODELAY(我连接到它们),但这只有在我不尝试一次发送多条消息时才有用。如果我连续有几个传出消息,那些消息往往会在一个或两个以太网帧中结束,这会导致另一个系统出现问题。
我通常可以通过使用计时器来避免问题,以避免过于靠近地发送消息,但这显然限制了我们的吞吐量。此外,如果我把时间调低得太低,我冒着网络拥塞的风险,阻止数据包传输,并最终允许我的多条消息进入同一个数据包。
有什么办法可以判断驱动程序是否有数据排队?有什么方法可以强制驱动程序在独立的传输层数据包中发送独立的写入调用?我已经查看了socket(7)和tcp(7)手册页,但我没有找到任何内容。可能只是因为我不知道我在寻找什么。
显然,UDP将是一条出路,但同样,我认为我们不能在另一方面做出任何改变。
非常感谢任何帮助。
答案 0 :(得分:9)
IIUC,设置TCP_NODELAY选项应该刷新所有数据包(即tcp.c通过调用tcp_push_pending_frames实现NODELAY的设置)。因此,如果您在每次发送呼叫后设置套接字选项,您应该得到您想要的。
答案 1 :(得分:2)
除非您确定问题是什么,否则无法解决问题。
如果他们已经完成了新手错误,假设recv()只收到一条消息,那么我就没有办法完全解决它。每个以太网帧只发送一条消息是一回事,但如果多个以太网帧在接收方呼叫recv()之前到达,它仍将在一次呼叫中获得多条消息。
网络拥塞使得实际上不可能阻止这种情况(同时保持良好的吞吐量),即使他们可以告诉你他们调用recv()的频率。
答案 2 :(得分:1)
也许,设置TCP_NODELAY并将你的MTU设置得足够低,这样每帧最多可以有1条消息?哦,并在传出数据包上添加“dont-fragment”标志
答案 3 :(得分:0)
您是否尝试为每条消息打开一个新套接字并立即关闭它?开销可能令人作呕,但这应该划分你的消息。
答案 4 :(得分:0)
在最糟糕的情况下,你可以降低一级(原始套接字),你可以更好地控制发送的数据包,但是你必须处理TCP的所有细节。
答案 5 :(得分:-1)
也许您可以尝试将tcp堆栈置于低延迟模式:
echo 1 > /proc/sys/net/ipv4/tcp_low_latency
这应该有利于在组合数据时尽快发送数据包。请阅读tcp(7)上的man以获取更多信息。