我陷入了一个非常奇怪的情况。我一直在玩sockets
和PIL
库,并且准备将客户端捕获的图像发送到服务器。通过套接字将图像发送到外部服务器时丢失数据
如果我在本地机器上测试它,一切都按预期进行。所有数据都将被服务器接收,最终可以制作图像。
但是,如果我想将图像发送到不在本地网络上的外部服务器,则剩余的几个字节尚未发送。
客户端代码:
# make a screenshot and store it as bytes
raw_image = ImageGrab.grab().tobytes()
print('Actual image size: {}'.format(len(raw_image)))
# send the image resolution to the server
raw_size = str.encode('{}\n{}'.format(image.size[0], image.size[1]))
sock.send(raw_size)
x = 512
y = 0
while y < len(raw_image):
sock.send(raw_image[y:x])
y = x
x += 512
# tell the server that the client is done sending the data
sock.send(b'sent')
我送一点二值图像内容比特(每个),直到一切都已经发送。
Server代码:
# receiving the image size for later usage
img_size = str(conn.recv(1024), 'utf-8', errors='ignore')
width = int(img_size.split('\n')[0])
height = int(img_size.split('\n')[1])
# receiving the binary data
raw_img = b''
while True:
raw_prt = conn.recv(512)
# "sent" will be sent by the client indicating that all data has been transferred
if b'sent' in raw_prt:
break
raw_img += raw_prt
print('Received image size: {}'.format(len(raw_img)))
客户端输出:
Actual image size: 6220800
服务器输出:
Received image size: 6220751
正如您所见,还有49 bytes
尚未收到。丢失的字节数量从30
到200
不等。这对于从二进制文件创建映像至关重要。我究竟做错了什么?
谢谢。
如果第一个'conn.recv(8)'只接收到6个字节会怎么样?你还需要一个循环来获得第一个接收。 –
是的,你说得对。我应该做到这一点。在实践中,我知道没有一个实现不会在单个数据包中传送8个字节的初始“发送”,而8个字节的相应“recv”不会获得全部8个字节。但是,如果这是一个从循环 - 发送几个文件,说 - 可能[并可能最终会*]成为一个问题。我会更新答案。 –
+1,我同意你的看法,但是你所做的一切都可能会被复制并永久粘贴。这就是为什么尽可能编写最健壮的代码片段总是好的。 –