为什么要在套接字的"recv"方法上设置保守的最大字节大小?
Why Should I Set a Conservative Max Byte Size on a Socket's 'recv' Method?
我正在使用Python的套接字构建一个客户端。套接字类,接收大小不等的数据(通常在500到5,000字节之间,但理论上客户端套接字可以接收500,000字节)。我还编写了将与此客户端套接字通信的服务器。
我很想知道,设置一个我确信永远不会超过的最大字节大小的风险是什么,比如:
socket.recv(1000000)
你所做的一切都是在大规模地浪费内存。
-
如果你以最大速度读取,你永远不会得到超过路径MTU,它通常在1500字节以下,当然是以千字节为单位测量的,而不是兆字节。
-
如果你没有以最大速度读取,内核中已经有一个套接字接收缓冲区,它的大小在8-64k之间,这取决于你的平台,通过TCP的操作,recv()完全不可能交付比缓冲区中更多的数据。
套接字并不像你想象的那样工作。socket.recv(N)
并不意味着你会得到N个字节。这意味着您将返回最多 N个字节的。这与发送方试图向您发送多少字节无关。TCP是面向流的。这意味着您将按照发送者发送的顺序获得发送者发送给您的字节。但是你将不会得到他们在发送数据时使用的相同的"消息"边界。
您必须编写代码以便能够多次调用recv,因为众所周知,socket.recv(1000000)
将返回一个字节给您。现在只要你多次调用它,你不需要考虑参数的大小和你接收到的消息的大小的比较。正如其他发帖者所说,你希望传递的值与堆栈其他级别上最大缓冲区的大小相当。其中一个缓冲区(路径MTU)可能在1500左右(但它可以更大或更小)。但是内核的TCP/IP堆栈中的本地接收缓冲区更大,可能在64k或128k左右。这些可能接近合理的使用值。
但是,我建议不要在这个级别编写网络代码。已经有人这么做了——或多或少是死的。您可能会更好地关注应用程序的新部分,并重用一些为您处理这些细节的现有库。我推荐Twisted.
- 具有使用 UDP 套接字字节的限制的标头
- UDP 套接字读取最后一个传入字节
- Qt TCP 套接字 - 写入超过 15 个字节
- 为什么 sys 套接字 recv 函数不填充数据但返回字节长度?
- C++,在阻塞模式下从套接字读取所有可用字节的最佳方法
- 从套接字到字节数组的读取数据中的意外字符
- C 套接字仅发送第4个字节的数据
- C++套接字不能接收超过 21845 字节
- 根据C++代码在 PHP 中创建字节数据并将其传递给套接字
- 发送的字节不等于C 套接字PRG中的接收字节
- 增强ASIO TCP套接字可用报告不正确的字节数
- Qt套接字未等待写入字节
- recv套接字中的前几个字节,以确定缓冲区大小
- boost::asio 从套接字读取 n 个字节到 Streambuf
- 通过套接字发送字节*
- 套接字 - Java 未以正确的编码接收字节
- 通过套接字从Linux向Windows机器发送空字节-会是一样的吗
- 如何在linux上获得异步套接字上可读取的字节数
- ZeroMQ-使用REQ套接字发送超过30个字节
- 套接字recv(),每次一个字节