7

我遇到了一个不寻常的情况:我在嵌入式环境中使用 Linux 系统(Intel box,目前使用 2.6.20 内核。)它必须与 TCP 实现部分损坏的嵌入式系统通信。据我所知,他们希望我们的每条消息都出现在单独的以太网帧中!当消息跨以太网帧拆分时,它们似乎有问题。

我们与设备在本地网络上,我们之间没有路由器(只是一个交换机)。

当然,我们正试图强迫他们修复他们的系统,但这可能最终不可行。

我已经在我的套接字上设置了 TCP_NODELAY(我连接到它们),但这只有在我不尝试一次发送多个消息时才有帮助。如果我连续有几条传出消息,这些消息往往会以一个或两个以太网帧结束,这会导致另一个系统出现问题。

我通常可以通过使用计时器来避免这个问题,以避免将消息发送得太近,但这显然会限制我们的吞吐量。此外,如果我把时间调得太低,我会冒网络拥塞阻碍数据包传输的风险,最终导致我的多个消息进入同一个数据包。

有什么方法可以判断驱动程序是否有数据排队?有什么方法可以强制驱动程序在独立的传输层数据包中发送独立的写调用?我查看了 socket(7) 和 tcp(7) 手册页,但没有找到任何东西。可能只是我不知道我在寻找什么。

显然,UDP 将是一种出路,但同样,我认为我们不能让另一端在这一点上做出任何改变。

非常感谢任何帮助。

4

6 回答 6

11

IIUC,设置 TCP_NODELAY 选项应该刷新所有数据包(即 tcp.c 通过调用 tcp_push_pending_frames 来实现 NODELAY 的设置)。所以如果你在每次发送调用后设置套接字选项,你应该得到你想要的。

于 2008-11-03T15:07:49.313 回答
2

除非您确定问题是什么,否则您无法解决问题。

如果他们犯了假设 recv() 只收到一条消息的新手错误,那么我看不到完全解决它的方法。每个以太网帧只发送一条消息是一回事,但如果多个以太网帧在接收方调用 recv() 之前到达,它仍然会在一次调用中获得多条消息。

网络拥塞使得实际上不可能防止这种情况(同时保持良好的吞吐量),即使他们可以告诉你他们多久调用一次 recv()。

于 2008-11-05T10:21:48.983 回答
1

也许,设置 TCP_NODELAY 并将 MTU 设置得足够低,以便每帧最多有 1 条消息?哦,在传出的数据包上添加“dont-fragment”标志

于 2008-11-03T16:28:30.227 回答
0

您是否尝试过为每条消息打开一个新套接字并立即关闭它?开销可能令人作呕,但这应该限制您的消息。

于 2008-11-03T16:35:23.303 回答
0

在最坏的情况下,您可以降低一级(原始套接字),在那里您可以更好地控制发送的数据包,但是您必须处理 TCP 的所有细节。

于 2008-11-03T16:45:04.923 回答
-1

也许您可以尝试将 tcp 堆栈置于低延迟模式:

echo 1 > /proc/sys/net/ipv4/tcp_low_latency

这应该有利于尽可能快地发送数据包而不是组合数据。阅读有关 tcp(7) 的手册以获取更多信息。

于 2008-11-03T18:33:20.773 回答