gpt4 book ai didi

python - Zlib 无法解压 python 2.7

转载 作者:行者123 更新时间:2023-12-01 02:02:19 25 4
gpt4 key购买 nike

我正在尝试通过套接字将数据从服务器移动到客户端。
我尝试压缩来自服务器的数据并将其发送到套接字,
但是当我尝试在客户端中解压缩时,出现此错误:

zlib.error: Error -5 while decompressing data: incomplete or truncated stream

我想我知道为什么,但我不明白为什么会发生。也许是因为我尝试解压缩“未压缩”数据,因为如果客户端获得数据,它不知道数据是否被压缩,并且现在尝试压缩它会导致错误。也许我完全错了,但我不知道如何解决它,我需要你的帮助。

客户端:获取数据(代表图像的字符串)

def room_client(port,ip):
roomC = socket.socket()
roomC.connect((ip, port))


while True:
print 'in while of client server'
#recv pict
#display
#send ack

img = ""
size = roomC.recv(1024)
roomC.sendall(size)

while len(img) < int(size):
data = roomC.recv(1024)
img += data

roomC.send("ACK")
to_pic = img.split('@')[0]
print to_pic
scrn = open("monitor_serv.png", "wb")
scrn.write(zlib.decompress(to_pic))
scrn.close()

服务器:发送图像(截图)

def room_server(port):
#sends pictures
print 'in room_server '
roomS = socket.socket()
roomS.bind(('0.0.0.0',port))
roomS.listen(1)

client, addr = roomS.accept()




while True:
print 'in while of room server'
# take picture
# send picture
# recv ack

flag = True
img1 = ImageGrab.grab()
send = zlib.compress(img1.tobytes())
size = img1.size

send = send + "@" + str(size[0]) + "@"+ str(size[1]) + "@0@0"
client.sendall(str(len(send)))
print "0"
f = client.recv(1024)
print "A ", f
client.sendall(send)
g = client.recv(1024)
print "C ", g
while True:
if flag:
flag = False
img2 = ImageGrab.grab()
coordinates = equal(img1, img2)
cropped_image = img2.crop(coordinates)

else:
flag = True
img1 = ImageGrab.grab()
coordinates = equal(img1, img2)
cropped_image = img1.crop(coordinates)

if coordinates is not None:
size = cropped_image.size
send = zlib.compress(cropped_image.tobytes())
try:
send = send + "@" + str(size[0]) + "@" + \
str(size[1]) + "@" + str(coordinates[0]) + "@" + str(coordinates[1])

client.sendall(str(len(send)))
client.recv(1024)

client.sendall(send)
client.recv(1024)
except:
break

最佳答案

在服务器上,您将发送以下内容:

send = zlib.compress(img1.tobytes())
size = img1.size

send = send + "@" + str(size[0]) + "@"+ str(size[1]) + "@0@0"

在客户端,您可以像这样解析它:

to_pic = img.split('@')[0]
print to_pic
scrn = open("monitor_serv.png", "wb")
scrn.write(zlib.decompress(to_pic))

几乎所有任意压缩文件中都会有一个@字节。因此,您的 to_pic 将在第一个处被截断。这意味着 zlib 几乎总是会给你一个错误,说你给它的流被截断了。

您需要想出一些其他方法来构建数据。一些选项:

  • 您可以只发送以其字节长度、宽度为前缀的 data,而不是发送以该字符串的字节长度为前缀的 data@width@height@0@0和高度。
  • 如果您想使用 @ 作为分隔符,您可以转义实际图像数据中的任何 @ 字节,然后在另一侧取消转义。例如,您可以replace('@', '@@'),然后在第一个@ 符号上re.split,然后replace('@@', '@')
  • 如果你rsplit来完成最后四个@,而不是split来完成第一个......这有点hacky,但它在这里可以工作,因为其他字段中都不能有 @,只有压缩图像数据字段。
<小时/>

协议(protocol)框架还有其他问题需要您重新考虑,但当您通过本地主机套接字发送小文件时,这些问题只会偶尔出现;这是唯一一个几乎每次都会出现的问题。不幸的是,这并不意味着您不需要修复其他问题。这只是意味着它们将更难调试。

<小时/>

同时,您的设计还存在另一个缺陷:

您从 ImageGrab.grab() 返回的内容(甚至在裁剪之前)不是 PNG 图像,而是原始 PIL/Pillow Image 数据。您在服务器上压缩它,在客户端上解压缩它,然后将这些字节保存为 PNG 文件。你不能这样做。

一种选择是在客户端上也使用 Pillow:从解压缩的字节创建一个 Image 对象,然后告诉它将自身保存到 PNG 文件。

另一个选择是让服务器导出为 PNG 格式的字节,而不是提供原始字节。这个版本有两大优点:客户端不需要安装 PIL,PNG 数据已经被压缩,因此您可以废弃所有 zlib 内容并编写更简单的代码。

关于python - Zlib 无法解压 python 2.7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49471718/

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