【问题标题】:Specify packet size with Ruby TCPSocket使用 Ruby TCPSocket 指定数据包大小
【发布时间】:2009-11-02 13:31:32
【问题描述】:

我正在使用 Ruby 测试一个使用套接字的 C# 网络应用程序。我打开与@socket = TCPSocket.new(IP,PORT) 的连接并且它可以工作 - 直到我要发送的文本长度超过 1024 个字符。然后 Ruby 将消息分成两部分。 C++ 和 C# 将消息作为一个数据包发送,因此 C# 应用程序不需要加入这些部分。

消息永远不会超过大约。 2000 个字符。是否可以设置 TCPSocket 的数据包大小?

编辑: 你所有的答案都是正确的,但是在阅读了很多关于 SO 的 ruby​​ socket 问题之后,我找到了解决方案:

socket.send(msg,0x4)

不拆分消息。直接发送选项会有所不同。

我不知道这是否适用于互联网,但它适用于我的测试实验室。

感谢您的帮助。

【问题讨论】:

  • 您不应该将 TCP 用作数据报协议。 TCP 抽象是一个流——你的服务器不应该关心单个数据包。无论如何,如果 Ruby 不会弄乱你的数据包,那么一些中介(例如路由器)可能会。

标签: ruby sockets


【解决方案1】:

TCP 是一种流协议。它不关心应用程序“消息”。 TCP 理论上可以在一个数据包或 1024 个数据包中发送您的 1024 个字节。 也就是说,请记住以太网MTU 是 1500 字节。考虑IP header(通常为 20)和TCP header(至少为 20)。那么您的 2000 字符消息必须以至少两个数据包的形式发送。 TCP 还进行流量控制,这可能与问题有关。找出网络上发生了什么的最好方法是使用tcpdumpwireshark

【讨论】:

    【解决方案2】:

    实际上,传输数据所需的数据包数量对流的影响应该很小。您可能会在实现中遇到缓冲问题。

    只有当套接字处于“可写”状态时才应写入套接字,否则可能会溢出输出缓冲区并导致连接被网络堆栈丢弃。

    由于 TCP/IP 套接字的功能是一个简单的流,数据按顺序输入和输出,因此数据包分段的影响应该几乎无关紧要,除非是对时间非常敏感的应用程序。

    确保在写入套接字时刷新输出缓冲区,否则可能还有一些数据等待传输:

    @socket.write(my_data)
    @socket.flush
    

    【讨论】: