- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试通过套接字将数据从服务器移动到客户端。
我尝试压缩来自服务器的数据并将其发送到套接字,
但是当我尝试在客户端中解压缩时,出现此错误:
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/
我是一名优秀的程序员,十分优秀!