2010-03-02 51 views
4

我对使用Ubuntu下的Berkeley套接字有疑问。在性能和可靠性方面哪个选项最好?发送大量短信但发送短信或发送少量信息,但发送大量信息?我不知道我应该在这里遵循哪个主要设计规则。套接字:大消息性能

谢谢大家!

+2

您使用的是SOCK_STREAM还是SOCK_DGRAM套接字? – msw 2010-03-02 15:36:19

+1

由于TCP是一个流,消息大小由协议确定,而不是您的应用程序。流 - 整体 - 没有大小。 – 2010-03-02 15:54:17

+0

我正在使用TCP。 – Julen 2010-03-03 12:01:33

回答

0

每个网络消息都有一个40字节长度的标题,但大消息很难路由并且更容易丢失。如果您在谈论UDP,那么最好的消息大小是以太网块,如果yiu使用TCP,那么它的长度是1496字节,将它留给网络层来处理发送的数量。

1

就可靠性而言,除非您有非常具体的要求,否则不值得担心。如果你谈论的是TCP,它会比管理事情做得更好,直到遇到一些确实需要你摆弄一些旋钮的边缘案例,在这种情况下,会有一个更具体的问题。在数据包大小方面,除非你规避Nagel's algorithm,否则你并不真正拥有你可能想到的控制。

对于UDP,可以说最好的做法是使用path MTU discovery,TCP自动为你做,但作为一般规则,你可以使用500字节范围内的东西。如果你开始变得太花哨,你会发现自己重新发明了TCP的一部分。

0

表现你可以用iperf找到自己。运行一些实验,你会自己看到它。至于可靠性,据我了解,如果你使用TCP TCP连接保证数据将被传递,当然如果连接没有中断。

1

对于TCP,一个选项是使用TCP_CORK套接字选项。请参阅getsockopt手册页。在套接字上设置TCP_CORK,写入一批小消息,然后删除TCP_CORK选项,它们将以最少数量的网络数据包进行传输。这可以增加吞吐量,但会增加延迟。

+0

看起来像这是仅限于Linux(这可能不是问题)。 – 2010-03-02 16:30:17

0

“在性能和可靠性的选项而言是最好的”

在有损层,性能和可靠性几乎是一条直线权衡彼此,和更大的专家比我们已经把多年的工作进入寻找甜蜜点,以及击败直接交易并同时改善的技术。

您有两个基本选项:

1)使用流套接字(TCP)。应用程序知道的任何“消息”都是在应用程序层而不是在套接字上定义的。例如,您可能会认为HTTP请求是一条消息,而响应是另一个方向相反的方向。您应该看到您的工作是尽可能保持输出缓冲区尽可能完整,并且输入缓冲区始终为空。可靠性几乎与消息长度无关,对于固定大小的数据性能,主要取决于执行的请求响应往返次数,而不是套接字上单个写入的次数。很明显,如果你一次发送一个字节的TCP_NODELAY,那么你会失去性能,但这是非常极端的。

2)使用数据报(UDP)。 “消息”是套接字层实体。性能可能比TCP更好,但是您必须为可靠性创建自己的系统,并且可能会通过要求重新发送数据来影响性能。 TCP具有相同的问题,但思路更加敏锐等。数据报长度与性能和可靠性之间的交互非常笨拙,因此Duck提到了MTU发现。如果你发送一个大包并且它被分割了,那么如果有任何一个片段误入歧途,那么你的消息就不会到达。有一个N的大小,如果你发送N大小的数据报,它们不会被分割,但是如果你发送N + 1大小的数据报,它们就会发送。因此,+1使失败消息的数量增加一倍。你不知道N,直到你知道网络路线(甚至可能还没有)。因此,在编译时基本不可能说什么尺寸会带来很好的性能:即使你测量它,对于不同的用户也会有所不同。如果你想优化,没有别的选择知道你的东西。

如果您需要可靠性,TCP内置于UDP,UDP也比TCP更有效。潜在的UDP有很大的回报,但应该被认为是套接字的汇编编程。

还有(3):使用协议来提高UDP可靠性,如RUDP。这不是伯克利风格套接字API的一部分,所以你需要一个库来提供帮助。