代码之家  ›  专栏  ›  技术社区  ›  Michael Kohne

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

  •  7
  • Michael Kohne  · 技术社区  · 16 年前

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

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

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

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

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

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

    显然,UDP将是一种出路,但我再次认为,在这一点上,我们不能让另一端发生太大变化。

    非常感谢任何帮助。

    6 回复  |  直到 16 年前
        1
  •  8
  •   Martin v. Löwis    16 年前

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

        2
  •  2
  •   Tommy    16 年前

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

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

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

        3
  •  1
  •   ADEpt    16 年前

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

        4
  •  0
  •   Adam Liss    16 年前

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

        5
  •  0
  •   Alexander    16 年前

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

        6
  •  -1
  •   Steve Baker    16 年前

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

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

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