我有一个客户端和一个服务器,服务器需要在其中向客户端发送许多文本文件。
发送文件功能接收套接字和要发送的文件的路径:
CHUNKSIZE = 1_000_000
def send_file(sock, filepath):
with open(filepath, 'rb') as f:
sock.sendall(f'{os.path.getsize(filepath)}'.encode() + b'\r\n')
# Send the file in chunks so large files can be handled.
while True:
data = f.read(CHUNKSIZE)
if not data:
break
sock.send(data)
接收文件功能接收客户端套接字和保存传入文件的路径:CHUNKSIZE = 1_000_000
def receive_file(sock, filepath):
with sock.makefile('rb') as file_socket:
length = int(file_socket.readline())
# Read the data in chunks so it can handle large files.
with open(filepath, 'wb') as f:
while length:
chunk = min(length, CHUNKSIZE)
data = file_socket.read(chunk)
if not data:
break
f.write(data)
length -= len(data)
if length != 0:
print('Invalid download.')
else:
print('Done.')
它的工作方式是将文件大小作为第一行发送,然后逐行发送文本文件。两者都在客户端和服务器中循环调用,以便文件被发送和保存。
如果我放置一个断点并缓慢地调用这些函数,它将很好地工作。但是,如果我让程序不间断运行,则在读取第二个文件的大小时它将失败:
File "/home/stark/Work/test/networking.py", line 29, in receive_file
length = int(file_socket.readline())
ValueError: invalid literal for int() with base 10: b'00,1851,-34,-58,782,-11.91,13.87,-99.55,1730,-16,-32,545,-12.12,19.70,-99.55,1564,-8,-10,177,-12.53,24.90,-99.55,1564,-8,-5,88,-12.53,25.99,-99.55,1564,-8,-3,43,-12.53,26.54,-99.55,0,60,0\r\n'
显然,该length = int(file_socket.readline())
行正在接收更多数据。我的问题:那是为什么?鉴于该行始终以尾随
\n
发送,因此该行不应该仅读取其大小吗?如何解决此问题,以便可以连续发送多个文件?
谢谢!
最佳答案
似乎您正在重用相同的连接,发生的是缓冲的file_socket
意味着...您实际上已经从套接字中进一步添加了recv
,然后考虑了读取循环。
IE。接收器会从您的套接字中消耗更多数据,而下次您尝试使用readline()
时,最终将读取剩余的前一个文件,直到包含在其中的新行或下一个长度信息。
这也意味着您最初的问题实际上是您跳过了一段时间。下一个读取行的影响不是您期望的int
,因此不是所观察到的故障。
你可以说:
with sock.makefile('rb', buffering=0) as file_socket:
而是强制对文件进行无缓冲访问。或者实际由您自己(而不是像wrapper和readline
这样的文件)来处理传入字节(理解一个文件结束,下一个开始)的接收,缓冲和解析。
关于python - 为什么这些Python发送/接收套接字函数在调用缓慢的情况下会起作用,而在连续调用很快的情况下会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63622224/