使用tcp进行图像网络收发。主要分为两个部分:
1、服务端
step1、启动服务,等待客户端连接;
step2、等待并接受客户端数据;
step3、接收的二进制流解码,显示;
step4、关闭服务;
2、客户端
step1、建立socket客户端,连接主机;
step2、读取,转二进制编码;
step3、发送;
step4、关闭服务;
服务端逻辑,serve.py:
#!/usr/bin/env python
# coding: utf-8
import cv2
import socket
import numpy as np
def receive_all(sock, count):
buf = b''
while count:
new_buf = sock.recv(count)
if not new_buf:
return None
buf += new_buf
count -= len(new_buf)
return buf
def main():
ip = 'localhost'
port = 6002
# 初始化socket,设置为监听状态
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ip, port))
s.listen(True)
# 等待并接收数据
conn, address = s.accept()
length = receive_all(conn, 16)
str_data = receive_all(conn, int(length))
s.close()
# 接收二进制数据流解码
data = np.fromstring(str_data, dtype='uint8')
decode_img = cv2.imdecode(data, 1)
cv2.imshow('serve', decode_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
pass
客户端逻辑,client.py:
#!/usr/bin/env python
# coding: utf-8
import cv2
import socket
import numpy as np
def main():
img_path = r"E:\test\img.jpg"
ip = 'localhost'
port = 6002
# 建立socket客户端,连接主机
sock = socket.socket()
sock.connect((ip, port))
# 图像二进制编码
img = cv2.imread(img_path)
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
result, img_encode = cv2.imencode('.jpg', img, encode_param)
data = np.array(img_encode)
str_data = data.tostring()
# 发送
sock.send(str(len(str_data)).ljust(16).encode())
sock.send(str_data)
sock.close()
# 解码为图像,显示发送的二进制流
decode_img = cv2.imdecode(data, 1)
cv2.imshow('client', decode_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
pass
结果:
容易出现的问题(摘自知乎:https://zhuanlan.zhihu.com/p/81512504):
1、代码没有问题,但是连接总失败
解决方法:
第一步,检查ip,是否是同一局域网内Client端的ip地址;
第二步,检查端口,Client端和Server端的代码里端口必须设置一致,并检查端口是否被占用;
第三步:检查防火墙,把Server端的防火墙关掉,防止防火墙阻挡连接。
2、图片传回来了,但传回来的图片有缺失 修改设置的参数“1024”,改成512或者更小,代价是传输图片需要花费的时间增加。本例中设置的为16。
其它参考资料:
1、python_socket 图像网络传输
python_socket 图像网络传输 - 刘文华 - 博客园
2、python建立socket通信传输图像-提供API函数说明