1 回答
TA贡献1811条经验 获得超4个赞
我建议你先发送长度,然后发送数据。
当服务器接收到“有效负载”长度时,它知道需要多少数据字节。
客户端:
len(f)
以8
字节形式发送发送数据
f
服务器:
接收
8
字节以获取len_f
.接收
len_f
数据字节。
无需以 1024 字节块的形式接收数据。
在我的示例中,len_f
被编码为base64
格式。
发送的字节数len_f
始终为 8 个字节(由于 base64 自动填充)。
data
您也可以编码base64
。
如果您通过 HTTP 发送数据,这一点很重要。
我将base64
图像数据的编码/解码放在注释中。
只有长度被编码为base64
(您也可以将长度作为文本格式发送)。
客户:
import socket
import numpy as np
import cv2
import base64
s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
s.connect(("127.0.0.1", 60124))
width, height, n_frames = 640, 480, 100 # 100 frames, resolution 640x480
for i in range(n_frames):
# Generate synthetic image:
img = np.full((height, width, 3), 60, np.uint8)
cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20) # Green number
# JPEG Encode img into f
_, f = cv2.imencode('.JPEG', img)
# Encode jpeg_img to base64 format
#f = base64.b64encode(f)
# Get length of f and encode to base64
#f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))
f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))
# Send the length first - so the server knows how many bytes to expect.
s.sendall(f_len) # Send 8 bytes (assumption: b64encode of 4 bytes will be 8 bytes due to the automatic padding feature).
s.sendall(f)
s.close()
服务器:
import socket
import numpy as np
import cv2
import base64
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 60124))
s.listen(5)
c, a = s.accept()
while True:
# Read 8 bytes that tells the length of encoded image to be expected.
data = c.recv(8)
if len(data) != 8:
break
# Decode f_len from base64
f_len = base64.decodebytes(data)
# Convet from array of 4 bytes to integer value.
f_len = int.from_bytes(f_len, byteorder='little')
#f = c.recv(1024)
# Receive the encoded image.
data = c.recv(f_len)
if len(data) != f_len:
break
#x = base64.decodebytes(data) # Decode base64
#x = np.fromstring(x , np.uint8)
x = np.fromstring(data, np.uint8)
var = cv2.imdecode(x, cv2.IMREAD_COLOR)
if var is None:
print('Invalid image')
else:
cv2.imshow("Camera" , var)
cv2.waitKey(100)
s.close()
cv2.destroyAllWindows()
添加回答
举报