Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 我应该分块发送数据,还是一次发送所有数据?_Python 3.x_Sockets - Fatal编程技术网

Python 3.x 我应该分块发送数据,还是一次发送所有数据?

Python 3.x 我应该分块发送数据,还是一次发送所有数据?,python-3.x,sockets,Python 3.x,Sockets,我有将数据发送到socket(一个相当大的文件)的python代码。我应该把它分成1kb的块,还是只接受conn.sendall(file.read())?这对发送操作没有什么影响。(我假设您正在使用TCP套接字进行讨论。) 当您尝试发送1K时,内核将获取该1K,将其复制到内核TCP缓冲区中,并返回成功(可能同时开始发送到对等方)。在这一点上,你将发送另一个1K和同样的事情发生。最终,如果文件足够大,网络无法足够快地发送它,或者接收者无法足够快地释放它,那么数据使用的内核缓冲区空间将达到某种内部

我有将数据发送到socket(一个相当大的文件)的python代码。我应该把它分成1kb的块,还是只接受
conn.sendall(file.read())

这对发送操作没有什么影响。(我假设您正在使用TCP套接字进行讨论。)

当您尝试发送1K时,内核将获取该1K,将其复制到内核TCP缓冲区中,并返回成功(可能同时开始发送到对等方)。在这一点上,你将发送另一个1K和同样的事情发生。最终,如果文件足够大,网络无法足够快地发送它,或者接收者无法足够快地释放它,那么数据使用的内核缓冲区空间将达到某种内部限制,并且进程将被阻塞,直到接收者释放足够多的数据。(TCP的这一限制通常相当高——根据操作系统的不同,您可以发送一到两兆字节的数据,而不会碰到它。)

如果您尝试一次性发送,几乎会发生相同的事情:数据将从缓冲区传输到内核缓冲区,直到/除非达到某个限制。在这一点上,您的进程将被阻塞,直到数据被接收器耗尽(以此类推)

但是,使用第一种机制,您可以发送任意大小的文件,而不需要使用过多的内存——内存缓冲区(不包括内核TCP缓冲区)只需要1K长。使用
sendall
方法,
file.read()
会将整个文件读取到程序内存中。如果您尝试使用一个真正巨大的文件(比如40G或其他文件),可能会占用比您更多的内存,甚至包括交换空间


因此,作为一种通用机制,我绝对支持第一种方法。对于现代体系结构,我会使用比1K更大的缓冲区大小。确切的数字可能并不太关键;但是,您可以选择一种可以同时容纳多个磁盘块的设备,例如256K。

以及您建议在接收端读取的大小?相同的一般方法:我将使用一个相当大但不太大的缓冲区(64K或256K)。由于TCP的工作方式,您很可能会得到仅部分填充的缓冲区。但无论如何,只需将接收到的每个块直接附加到文件中即可。(内核已经为聚合顺序写入的缓冲区优化了代码。在python中添加缓冲区只会导致不必要的额外内存拷贝。)