我用python编写了一个使用sockets发送文件的快速程序。在
服务器:
import socket, threading
#Create a socket object.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Bind the socket.
sock.bind( ("", 5050) )
#Start listening.
sock.listen()
#Accept client.
client, addr = sock.accept()
#Open a new file jpg file.
file = open("out.jpg", "wb")
#Receive all the bytes and write them into the file.
while True:
received = client.recv(5)
#Stop receiving.
if received == b'':
file.close()
break
#Write bytes into the file.
file.write( received )
客户:
^{pr2}$从经验中得知,发送可以发送一定数量的字节 发送它们的速度是可以的。如果你举个例子:短袜发送(20 gb)您将丢失字节,因为大多数网络连接无法在 一次。你必须一部分一部分地送他们。在
所以我的问题是:如何知道套接字.send() 可以通过互联网发送吗?如何根据我的网速来改进我的程序以尽可能快地发送文件?在
只需在循环中发送这些字节,直到所有字节都被发送,这里有一个example from the docs
在您的例子中,
MSGLEN
将是1024,并且由于您没有使用类,所以不需要自变量send
不能保证所有的数据都被发送(它与网络速度没有直接关系;有多种原因它可以发送比请求的少),只是它让你知道发送了多少。您可以显式地向send
写入循环,直到它真正发送完毕为止。在或者您可以使用^{} 来避免麻烦。
sendall
基本上是{a3}中描述的包装器,但是Python为您完成了所有繁重的工作。在如果您不在乎将整个文件拖入内存,可以使用以下命令替换整个循环结构:
如果您使用的是UNIX类操作系统上的现代Python(3.5或更高版本),您可以进行一些优化,以避免使用^{} 将文件数据读入Python(这只会导致出错时出现部分{}):
^{pr2}$如果Python在您的操作系统上不支持}的循环,但是在支持它的系统上,它直接从文件复制到内核中的套接字,甚至不用Python处理文件数据(通过减少系统调用和完全消除一些内存副本,可以显著提高吞吐量速度)。在
os.sendfile
,那么这只是一个有效的循环read
s和{在源和目标之间的所有步骤中都有输入/输出缓冲区。一旦缓冲区被填满,在没有空间可用之前,不会接受任何其他缓冲区。在
当您的应用程序尝试发送数据时,它将在操作系统中填充一个缓冲区,当操作系统能够将数据卸载到网络设备驱动程序(也有一个缓冲区)时,该缓冲区被清除。在
网络设备驱动程序与实际网络接口,并了解如何知道何时可以发送数据,以及如何由另一方确认接收(如果有的话)。当数据被发送时,缓冲区被清空,允许操作系统从缓冲区推送更多的数据。这反过来又为您的应用程序腾出空间将更多的数据推送到操作系统。在
还有很多其他因素会影响到这个过程(超时、最大跳数是两个,我可以马上考虑),但一般的过程是,你必须在每个步骤缓冲数据,直到它可以发送到下一个步骤。在
相关问题 更多 >
编程相关推荐