一些事情:
>使用sendall而不是发送,因为你不能保证一切都会一次发送
> pickle可以用于数据序列化,但你必须制定一个协议
你拥有客户端和服务器之间交换的消息,这个
你可以事先知道要读取的数据量(见
下面)
>对于recv,如果你收到大块,你将获得更好的性能,所以将80替换为4096甚至更多
>小心sys.getsizeof:它返回内存中对象的大小,而不是
与通过网络发送的字节的大小(长度)相同;为一个
Python字符串这两个值根本不相同
>注意您发送的帧的大小.下面的代码支持最大65535的帧.如果您有一个更大的帧,请将“H”更改为“L”.
协议示例:
client_cv.py
import cv2
import numpy as np
import socket
import sys
import pickle
import struct ### new code
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while True:
ret,frame=cap.read()
data = pickle.dumps(frame) ### new code
clientsocket.sendall(struct.pack("H", len(data))+data) ### new code
server_cv.py
import socket
import sys
import cv2
import pickle
import numpy as np
import struct ## new
HOST=''
PORT=8089
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print 'Socket created'
s.bind((HOST,PORT))
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
conn,addr=s.accept()
### new
data = ""
payload_size = struct.calcsize("H")
while True:
while len(data) < payload_size:
data += conn.recv(4096)
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("H", packed_msg_size)[0]
while len(data) < msg_size:
data += conn.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
###
frame=pickle.loads(frame_data)
print frame
cv2.imshow('frame',frame)
你可以大量优化所有这些(减少复制,使用缓冲接口等),但至少你可以得到这个想法.