简体   繁体   English

为什么要在套接字的“ recv”方法上设置保守的最大字节大小?

[英]Why Should I Set a Conservative Max Byte Size on a Socket's 'recv' Method?

I am building a client using Python's socket.socket class that receives data which varies in size (usually between 500 and 5,000 bytes but it is theoretically possible for the client socket to receive 500,000 bytes). 我正在使用Python的socket.socket类构建客户端,该类接收大小不同的数据(通常在500到5,000字节之间,但从理论上讲,客户端套接字可以接收500,000字节)。 I am also writing the server that will communicate with this client socket. 我也在编写将与此客户端套接字通信的服务器。

I am curious to know, what is the risk of setting a maximum byte size that I can be confident I will never exceed such as: 我很想知道,我可以确定自己永远不会超过的最大字节大小设置有什么风险,例如:

socket.recv(1000000)

even though I know this is far larger than 99% of the sockets actual usage. 即使我知道这远远超过套接字实际使用率的99%。

All you're doing is wasting memory on an epic scale. 您要做的只是浪费内存,数量如此之多。

  1. If you're reading at maximum speed, you will never get more than the path MTU, which is usually under 1500 bytes, and certainly measured in kilobytes, not megabytes. 如果您以最大速度阅读,那么您将获得的路径MTU通常不会超过1500字节,并且肯定以千字节而不是兆字节为单位。

  2. If you're not reading at maximum speed, there is already a socket receive buffer inside the kernel, which is sized somewhere in the range 8-64k depending on your platform, and by the operation of TCP it is entirely impossible for recv() to ever deliver more data than is in that buffer. 如果您不是以最大速度读取,则内核中已经有一个套接字接收缓冲区,根据您的平台,该缓冲区的大小在8-64k范围内,通过TCP的操作,recv()完全不可能传送的数据比该缓冲区中的要多。

Sockets don't work the way you think they do. 套接字不能像您想象的那样工作。 socket.recv(N) does not mean you will get back N bytes. socket.recv(N)并不意味着您将获得N个字节。 It means you will get back at most N bytes. 这意味着您最多可以取回N个字节。 This is regardless of how many bytes the sender tried to send you. 这与发送方尝试向您发送多少字节无关。 TCP is stream oriented . TCP是面向流的 This means you will get the bytes that the sender sent you, in the order they sent them. 这意味着您将按照发送方发送给您的顺序来获取发送方发送给您的字节。 But you will not get the same "message" boundaries that they used when sending the data. 但是您将不会获得与发送数据时使用的相同的“消息”边界。

You have to write your code to be able to call recv multiple times because for all you know, socket.recv(1000000) will return one byte to you. 必须编写代码才能多次调用recv,因为众所周知, socket.recv(1000000)将向您返回一个字节。 And now as long as you're calling it multiple times, you don't have to think about the size of the argument as compared to the size of the messages you're receiving. 现在,只要多次调用它,您就不必考虑参数的大小与接收到的消息的大小。 As other posters have said, you want to pass a value that's comparable to the size of the largest buffer at some other level of the stack. 就像其他张贴者所说的那样,您希望传递一个与堆栈其他级别的最大缓冲区大小可比的值。 One of those buffers (path MTU) is probably around 1500 (but it can be larger or smaller). 这些缓冲区之一(路径MTU)可能约为1500(但可以更大或更小)。 But the local receive buffer in your kernel's TCP/IP stack is larger, probably around 64k or 128k. 但是内核的TCP / IP堆栈中的本地接收缓冲区较大,可能约为64k或128k。 Those are probably close to reasonable values to use. 这些可能接近合理的使用值。

Though, I recommend not actually writing network code at this level. 不过,我建议不要实际在此级别上编写网络代码。 It's been done - more or less to death. 它已经完成了-或多或少地导致死亡。 You'd probably be a whole lot better off focusing on the novel part of your application and re-using some existing library that deals with these details for you. 将精力集中在应用程序的新颖部分上,并重新使用一些为您处理这些细节的现有库,可能会更好。 I recommend Twisted . 我推荐Twisted

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 套接字recv()一次一个字节 - Socket recv() one byte at a time 为什么我得到的双端队列的max_size()小于矢量的max_size()? - Why did I get deque's max_size() less than vector's max_size()? 在Windows上为套接字设置recv的超时 - Set a timeout for recv from socket on Windows 从套接字接收前几个字节以确定缓冲区大小 - recv the first few bytes from a socket to determine buffer size 我用winsock2在C ++中创建了一个简单的套接字,并将recv函数放入变量中,并给出了一些奇怪的符号 - I made a simple socket in C++ with winsock2 and I put the recv function into a variable and it's giving some weird symbols C++ Socket 编程:Accept 和 Recv 方法不会阻塞进程 - C++ Socket Programming : Accept and Recv method do not block the process 在单个 recv() 方法期间从套接字读取所有数据 - Read all data during single recv() method from a socket libev,为什么在evloop中接收事件的编号为3? - libev, why recv a event's number is 3 in evloop? 记忆保守的最大独立顶点集 - Memory conservative maximal independent set of vertices 将套接字发送/接收缓冲区的大小设置为大于sysctl max时,为什么没有错误? - Why no error when setting socket send/receive buffer size higher than sysctl max?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM