我对在Ubuntu下使用Berkeley套接字有疑问。在性能和可靠性方面哪个选项最好?发送大量短消息但是发送的消息很短或发送少量消息但是这些消息大吗?我不知道我应该遵循的主要设计规则是什么。
谢谢大家!
答案 0 :(得分:1)
在可靠性方面,除非你有非常具体的要求,否则不值得担心。如果你在谈论TCP,它会比你管理事情做得更好,直到你遇到一些真正需要你摆弄一些旋钮的边缘情况,在这种情况下,一个更具体的问题将是有序的。在数据包大小方面,除非你绕过Nagel's algorithm,否则使用TCP,你实际上并没有你想到的控制。
使用UDP,可以说最好的办法就是使用path MTU discovery,TCP会自动为你做,但作为一般规则,只需使用500字节范围内的东西即可。如果你开始变得过于花哨,你会发现自己重新发明了部分TCP。
答案 1 :(得分:1)
使用TCP,一个选项是使用TCP_CORK
套接字选项。请参见getsockopt
手册页。在套接字上设置TCP_CORK
,写一批小消息,然后删除TCP_CORK
选项,它们将以最少数量的网络数据包传输。这可能会增加吞吐量,但会增加延迟。
答案 2 :(得分:0)
每个网络消息都有一个40字节长的标题,但是大消息更难以路由并且更容易丢失。如果你在谈论UDP,那么最好的消息大小是以太网块,长度为1496字节,如果yiu正在使用TCP,则将其留给网络层来处理要发送的数量。
答案 3 :(得分:0)
您可以通过iperf了解自己的表现。运行一些实验,你会自己看到它。至于可靠性,据我所知,如果你使用TCP,TCP连接保证如果连接没有被破坏,数据将被传送。
答案 4 :(得分:0)
“在性能和可靠性方面哪个选项最好”
在一个有损的层面上,性能和可靠性几乎是相互之间的直接权衡,而且比我们更多的专家已经花费了多年的时间来寻找最佳点和技术,这些技术击败了直接的权衡并改善了一次。
您有两个基本选项:
1)使用流套接字(TCP)。应用程序知道的任何“消息”都是在应用程序层而不是套接字上定义的。例如,您可以将HTTP请求视为一条消息,将响应视为另一方向的响应。您应该看到您的工作是尽可能保持输出缓冲区尽可能完整,输入缓冲区尽可能为空。可靠性几乎与消息长度无关,并且对于固定大小的数据性能,主要取决于执行的请求 - 响应往返次数而不是套接字上的单个写入次数。显然,如果你使用TCP_NODELAY一次发送一个字节,那么你会失去性能,但这是非常极端的。
2)使用数据报(UDP)。 “消息”是套接字层实体。性能可能比TCP更好,但您必须创建自己的系统以确保可靠性,并且可能会通过要求重新发送数据来提高性能。 TCP具有相同的问题,但更多的思想,等等。数据报长度可以与性能和可靠性相互作用非常笨拙,因此Duck提到的MTU发现。如果您发送一个大数据包并且它已经碎片化,那么如果任何碎片误入歧途,那么您的消息将无法到达。有一个N大小,如果你发送N大小的数据报,他们不会碎片,但如果你发送N + 1大小的数据报,他们会。因此,+1使失败的消息数量翻倍。在你知道网络路由之前你不知道N(也许甚至不知道)。因此,在编译时基本上不可能说什么尺寸会提供良好的性能:即使你测量它,它对不同的用户也会有所不同。如果你想进行优化,除了了解你的东西之外别无选择。
如果你需要内置于TCP的可靠性,那么UDP也比TCP更有用。可能UDP有很大的收益,但应该被认为是套接字的汇编程序。还有(3):使用协议来提高UDP可靠性,例如RUDP。这不是Berkeley风格的套接字API的一部分,因此您需要一个库来帮助。