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

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

  •  6
  • 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设置得足够低,以便每帧最多有一条消息?哦,在发送的数据包上添加“不要分段”标志

        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)上的手册。