我制作了一个使用 python 中的套接字发送文件的快速程序。
服务器:
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 )
客户:
import socket, threading
#Create a socket object.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Connect to the server.
sock.connect(("192.168.1.3", 5050))
#Open a file for read.
file = open("cpp.jpg", "rb")
#Read first 5 bytes.
read = file.read(5)
#Keep sending bytes until reaching EOF.
while read != b'':
#Send bytes.
sock.send(read)
#Read next five bytes from the file.
read = file.read(1024)
sock.close()
file.close()
从经验中了解到发送可以发送您的网络的字节数 速度能够发送它们。例如,如果您给出:sock.send(20 gb) 您将丢失字节,因为大多数网络连接无法发送 20 gb 一次。您必须逐个发送它们。
所以我的问题是:我怎么知道 socket.send() 的最大字节数 可以通过互联网发送吗?如何改进我的程序以根据我的网速尽快发送文件?
请您参考如下方法:
send 不保证所有数据都已发送(它与网络速度没有直接关系;它发送的数据可能少于请求的数据有多种原因),只是它让您知道发送了多少数据发送。根据 Dunno's answer,您可以显式地将循环写入 send 直到真正发送完为止.
或者您可以只使用 sendall并避免麻烦。 sendall 基本上是 the other answer 中描述的包装器,但 Python 会为您完成所有繁重的工作。
如果您不关心将整个文件放入内存,您可以使用它来替换整个循环结构:
sock.sendall(file.read())
如果您在类 UNIX 操作系统上使用现代 Python(3.5 或更高版本),您可以进行一些优化以避免使用 socket.sendfile 甚至将文件数据读入 Python。 (这应该只会导致部分 send 出错):
sock.sendfile(file)
如果 Python 在您的操作系统上不支持 os.sendfile,这只是一个有效的 read 和 send 循环s 重复,但在支持它的系统上,这直接从文件复制到内核中的套接字,甚至不需要在 Python 中处理文件数据(这可以通过减少系统调用和完全消除一些内存副本来显着提高吞吐速度)。
