gpt4 book ai didi

python - 通过套接字发送二进制文件时出现问题,python

转载 作者:行者123 更新时间:2023-11-30 22:06:26 24 4
gpt4 key购买 nike

我正在尝试编写一个将二进制文件从客户端传输到服务器的程序。代码如下:

客户端(发送文件)

  def send_file(self,filename):
print("Sending: " + filename)
size = self.BUFFER_SIZE
with open(filename,'rb') as f:
raw = f.read().decode()
buffer = [raw[i:i + size] for i in range(0, len(raw), size)]
for x in range(len(buffer)):
self.sock.sendall(buffer[x].encode())

return

服务器(recv 文件)

def recv_file(self, conn, filename):
packet = ""
buffer = ""
while True:
buffer = conn.recv(self.BUFFER_SIZE)
packet = packet + str(buffer.decode())
if not len(buffer) == self.BUFFER_SIZE:
break
with open(filename, 'wb') as f:
f.write(bytes(packet.encode()))
#print(packet)
return

这样我可以传输txt文件,但是当我必须传输jpeg或任何其他类型的文件时,它会在循环中卡住。有人可以解释一下为什么吗?我是 py 新手,我正在努力学习

最佳答案

如果双方具有相同的区域设置编码,它不应该卡住,但它很容易因异常而死掉。

您正在以二进制形式读取和发送(很好),但莫名其妙地解码-ing为str,然后编码返回为字节(坏)。问题是,不能保证任意二进制数据在任何给定的语言环境中都是可解码的;如果您的区域设置编码是 UTF-8,那么它很可能是不合法的。如果它是 latin-1 它是合法的,但毫无意义。

更糟糕的是,如果您的客户端和服务器具有不同的区域设置编码,则双方的解码结果可能不同(因此长度不匹配)。

一致地使用字节,不要与字符串相互转换,区域设置也无关紧要。您的代码也会运行得更快。您还需要提前实际发送文件长度;您的循环希望 recv 仅在文件完成时返回较短的长度,但如果:

  1. 该文件是缓冲区大小的精确倍数,或者
  2. 套接字发送的数据 block 与缓冲区大小不匹配

你们每个人都可以得到简短的recv结果,在情况#2中是巧合,在情况#1中是确定性的。

更安全的方法是在传输中实际添加文件长度前缀,而不是希望分块按预期工作:

def send_file(self,filename):
print("Sending:", filename)
with open(filename, 'rb') as f:
raw = f.read()
# Send actual length ahead of data, with fixed byteorder and size
self.sock.sendall(len(raw).to_bytes(8, 'big'))
# You have the whole thing in memory anyway; don't bother chunking
self.sock.sendall(raw)

def recv_file(self, conn, filename):
# Get the expected length (eight bytes long, always)
expected_size = b""
while len(expected_size) < 8:
more_size = conn.recv(8 - len(expected_size))
if not more_size:
raise Exception("Short file length received")
expected_size += more_size

# Convert to int, the expected file length
expected_size = int.from_bytes(expected_size, 'big')

# Until we've received the expected amount of data, keep receiving
packet = b"" # Use bytes, not str, to accumulate
while len(packet) < expected_size:
buffer = conn.recv(expected_size - len(packet))
if not buffer:
raise Exception("Incomplete file received")
packet += buffer
with open(filename, 'wb') as f:
f.write(packet)

关于python - 通过套接字发送二进制文件时出现问题,python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52722787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com