我们正在使用.Net和套接字.服务器使用Socket.Sender(bytes [])方法,因此它只发送整个有效负载.另一方面,我们是消费数据的客户.Socket.Receive(缓冲液[]).在Microsoft(和其他人)的所有示例中,他们似乎都坚持使用8192的缓冲区大小.我们已经使用了这个大小,但我们偶尔会向超出此缓冲区大小的客户端发送数据.
有没有办法确定服务器发送方法发送给我们的数据量?什么是最好的缓冲区大小?
Jon*_*eet 40
即使您发送的数据多于此数据,也可能无法在一次调用Receive中使用.
您无法确定服务器发送了多少数据 - 它是一个数据流,您只是一次只读取数据块.您可以阅读服务器在一个发送呼叫中发送的部分内容,或者您可以从一个接收呼叫中的两个发送呼叫中读取数据.8K是一个合理的缓冲区大小 - 不是那么大,你会浪费大量的内存,而不是那么小,你将不得不使用大量浪费的接收调用.4K或16K很可能也很好......我个人不会开始超过16K的网络缓冲区 - 我怀疑你很少填充它们.
您可以通过尝试使用一个非常大的缓冲区并记录每次调用接收到多少字节来进行实验 - 这可以让您了解通常可用的数量 - 但它不会真正显示使用较小缓冲区的效果.您对使用8K缓冲区有什么顾虑?如果它的性能,您是否有任何证据表明您的代码的这一方面是性能瓶颈?
ant*_*duh 20
不幸的是,Jon Skeet的答案留下了很大一部分图片 - 发送缓冲区大小,以及您正在写入的管道的带宽延迟产品.
如果您尝试使用单个套接字通过大型管道发送数据,并且您希望TCP填充该管道,则需要使用等于管道的带宽延迟乘积的发送缓冲区大小.否则,TCP将不会填充管道,因为它不会始终留下足够的"飞行中的字节".
考虑速度为1千兆位的连接,平均单向延迟为10毫秒.往返时间(也就是说,套接字发送数据包之间经过的时间和接收该数据包的确认时间因此知道发送更多数据的时间)通常是延迟的两倍.
因此,如果您拥有1千兆位连接,并且RTT为20毫秒,那么如果完全使用该管道,则该管道始终具有1千兆位/秒*20毫秒== 2.5兆字节的数据.
如果您的TCP发送缓冲区小于2.5兆字节,那么一个套接字永远不会完全利用管道 - 您永远不会从套接字中获得千兆位/秒的性能.
如果您的应用程序使用多个套接字,则所有TCP发送缓冲区的聚合大小必须为2.5 MB,以便充分利用此假设的1千兆位/ 20毫秒RTT管道.例如,如果使用8192字节的缓冲区,则需要306个同时使用的TCP套接字来填充该管道.
这取决于您的协议.如果您期望超过8192字节的消息,则应相应地增加缓冲区大小.但请记住,此缓冲区大小仅适用于一次调用Receive.如果您真的需要/需要,可以Receive多次循环并将接收的数据复制到任意大的数据结构或缓冲区中.
另请注意,Receive在您确认已阅读给定消息的所有数据之前,最好重复调用; 即使单个消息小于缓冲区大小,单个Receive调用仍然可能无法检索到所有消息.
| 归档时间: |
|
| 查看次数: |
50889 次 |
| 最近记录: |