我需要一个 TCP 选项(ioctl)来立即发送数据

发布于 2024-07-08 03:17:45 字数 659 浏览 5 评论 0原文

我遇到了一个不寻常的情况:我正在嵌入式情况下使用 Linux 系统(Intel 盒子,当前使用 2.6.20 内核。),它必须与 TCP 实现部分损坏的嵌入式系统进行通信。 据我现在所知,他们希望我们发送的每条消息都来自一个单独的以太网帧! 当消息跨以太网帧分割时,它们似乎会遇到问题。

我们与设备位于本地网络上,并且我们之间没有路由器(只有交换机)。

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

我已经在我的套接字上设置了 TCP_NODELAY(我连接到它们),但这只有在我不尝试一次发送多条消息时才有帮助。 如果我连续有多个传出消息,这些消息往往会出现在一个或两个以太网帧中,这会给其他系统带来麻烦。

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

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

显然,UDP 是一种出路,但同样,我认为此时我们无法让另一端做出太大改变。

非常感谢任何帮助。

I've got an unusual situation: I'm using a Linux system in an embedded situation (Intel box, currently using a 2.6.20 kernel.) which has to communicate with an embedded system that has a partially broken TCP implementation. As near as I can tell right now they expect each message from us to come in a separate Ethernet frame! They seem to have problems when messages are split across Ethernet frames.

We are on the local network with the device, and there are no routers between us (just a switch).

We are, of course, trying to force them to fix their system, but that may not end up being feasible.

I've already set TCP_NODELAY on my sockets (I connect to them), but that only helps if I don't try to send more than one message at a time. If I have several outgoing messages in a row, those messages tend to end up in one or two Ethernet frames, which causes trouble on the other system.

I can generally avoid the problem by using a timer to avoid sending messages too close together, but that obviously limits our throughput. Further, if I turn the time down too low, I risk network congestion holding up packet transmits and ending up allowing more than one of my messages into the same packet.

Is there any way that I can tell whether the driver has data queued or not? Is there some way I can force the driver to send independent write calls in independent transport layer packets? I've had a look through the socket(7) and tcp(7) man pages and I didn't find anything. It may just be that I don't know what I'm looking for.

Obviously, UDP would be one way out, but again, I don't think we can make the other end change anything much at this point.

Any help greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

话少情深 2024-07-15 03:17:45

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

IIUC, setting the TCP_NODELAY option should flush all packets (i.e. tcp.c implements setting of NODELAY with a call to tcp_push_pending_frames). So if you set the socket option after each send call, you should get what you want.

留一抹残留的笑 2024-07-15 03:17:45

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

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

网络拥塞使得几乎不可能阻止这种情况(同时保持良好的吞吐量),即使他们可以告诉您他们调用 recv() 的频率。

You cannot work around a problem unless you're sure what the problem is.

If they've done the newbie mistake of assuming that recv() receives exactly one message then I don't see a way to solve it completely. Sending only one message per Ethernet frame is one thing, but if multiple Ethernet frames arrive before the receiver calls recv() it will still get multiple messages in one call.

Network congestion makes it practically impossible to prevent this (while maintaining decent throughput) even if they can tell you how often they call recv().

久随 2024-07-15 03:17:45

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

Maybe, set TCP_NODELAY and set your MTU low enough so that there would be at most 1 message per frame? Oh, and add "dont-fragment" flag on outgoing packets

嘿看小鸭子会跑 2024-07-15 03:17:45

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

Have you tried opening a new socket for each message and closing it immediately? The overhead may be nauseating,but this should delimit your messages.

你与清晨阳光 2024-07-15 03:17:45

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

In the worst case scenario you could go one level lower (raw sockets), where you have better control over the packets sent, but then you'd have to deal with all the nitty-gritty of TCP.

北斗星光 2024-07-15 03:17:45

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

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

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

Maybe you could try putting the tcp stack into low-latency mode:

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

That should favor emitting packets as quickly as possible over combining data. Read the man on tcp(7) for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文