我现在遇到了一个奇怪的错误。我有一个使用TCP套接字发送/接收数据的Python脚本,一切正常,但是当我尝试使用这个脚本下载图像时,它会下载,但是缺少一个像素行。你有什么解决方法吗?
服务器下载脚本:
def download(self, cmd):
try:
self.c.send(str.encode(cmd))
command,filename=cmd.split(' ')
nFile = open(filename, 'wb')
i = self.c.recv(1024)
while not ('complete' in str(i)):
nFile.write(i)
i = self.c.recv(1024)
nFile.close()
self.reset = True
print('\nGot that file')
except Exception as e:
print(e)
客户端上传脚本:
def upload(self, filename):
try:
fd = open(filename, 'rb')
data = fd.read(1024)
while (data):
self.s.sendall(data)
data = fd.read(1024)
self.s.send(str.encode('complete'))
fd.close()
except Exception as e:
print(e)
解决方案(1):这不是一个解决方案,只是一个变通方法,请使用另一个!
如果在向nFile写入最后一块数据之前,将有效载荷的完整部分全部删除会发生什么情况?-mtrw
问题出在发送“complete”字符串到服务器上,因为脚本没有足够的时间来获取图像中的所有字节。所以修复此问题的一种方法是向脚本添加sleep(0.2)。
客户端上传脚本:
def upload(self, filename):
try:
fd = open(filename, 'rb')
data = fd.read(1024)
while (data):
self.s.sendall(data)
data = fd.read(1024)
sleep(0.2)
self.s.send(str.encode('complete'))
fd.close()
except Exception as e:
print(e)
解决方案(2):
TCP是一种没有消息边界的流协议。这意味着多个发送可以在一个接收调用中接收,或者一个发送可以在多个接收调用中接收。
延迟解决方法可能无法可靠地工作。您需要在流中限定消息。
– Maxim Egorushkin
服务器下载脚本:
try:
msg_header = self.c.recv(4)
while len(msg_header) != 4:
msg_header += self.c.recv(4 - len(msg_header))
file_len = struct.unpack('<I', msg_header)[0]
nFile = open(filename, 'wb')
data = self.c.recv(file_len)
while len(data) != file_len:
data += self.c.recv(file_len - len(data))
nFile.write(data)
nFile.close()
print('\nGot that file')
except Exception as e:
print(e)
客户端上传脚本:
try:
file_len = os.stat(filename).st_size
msg_header = struct.pack('<I', file_len)
self.s.sendall(msg_header)
fd = open(filename, 'rb')
data = fd.read(file_len)
while (data):
self.s.sendall(data)
data = fd.read(file_len)
fd.close()
except Exception as e:
print(e)
nFile
之前删除负载的complete
部分,会发生什么? - mtrwint(file_len[0])
中进行int
转换是不必要的,因为它已经是一个int
。你还应该检查send
的返回值,因为不能保证会发送整个缓冲区。换句话说,使用循环来实现sendall
函数。 - Maxim Egorushkinint(...)
部分是不必要的。只需要file_len = struct.unpack('<I', msg_header)[0]
即可。虽然这只是一个小细节... - Maxim Egorushkin