我正在尝试通过套接字将数据从服务器移动到客户端
我尝试从服务器压缩数据并将其发送到套接字,
但当我尝试在客户端解压缩时,我收到此错误:
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
答案 0 :(得分:1)
在服务器上,您发送的是:
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@width@height@0@0
前缀为其字节长度,宽度和高度,而不是发送前缀为该字符串字节长度的data
。@
用作分隔符,则可以转义实际图像数据中的任何@
个字节,然后在另一侧转换为unescape。例如,您可以replace('@', '@@')
,然后re.split
在第一个@
个符号上,然后replace('@@', '@')
。rsplit
拉出最后四个@
而不是split
来取消第一个...这有点hacky,但它会在这里工作,因为没有其他字段中可能只有@
,只有压缩的图像数据字段。协议框架还有其他问题需要重新考虑,但是当你通过localhost套接字发送小文件时,它们只会偶尔出现;这是几乎每次都会出现的唯一一个。不幸的是,这并不意味着你不需要修复其他的;它只是意味着他们将更难调试。
与此同时,你的设计还有另一个缺陷:
从ImageGrab.grab()
获得的内容(甚至在裁剪之前)不是PNG图像,而是原始的PIL / Pillow Image
数据。您在服务器上压缩它,在客户端上解压缩它,并将这些字节保存为PNG文件。你不能这样做。
一种选择是在客户端上也使用Pillow:从解压缩的字节创建一个Image
对象,然后告诉它将自己保存到PNG文件中。
另一种选择是让服务器以PNG格式导出为字节,而不是为您提供原始字节。这个版本有两个很大的优点:不需要在客户端安装PIL,并且PNG数据已经被压缩,因此您可以废弃所有zlib内容并编写更简单的代码。