Socket树莓派实时传输到PC上

Socket树莓派实时传输到PC上

我们把PC端作为我们的服务端,树莓派作为我们的客户端。

PC端

#!/usr/bin/python
#-*-coding:utf-8 -*-
import socket
import cv2
import numpy
address = ('',8080) # 设置地址与端口,如果是接收任意ip对本服务器的连接,地址栏可空,但端口必须设置

class ServerSocket(object):
    def __init__(self):
        # socket.AF_INET用于服务器与服务器之间的网络通信
        # socket.SOCK_STREAM代表基于TCP的流式socket通信
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind(address) # 将Socket(套接字)绑定到地址
        self.server_socket.listen(True) # 开始监听TCP传入连接
        print('Waiting for images...')
# 接受图片大小的信息
    def recv_size(self,sock, count):
        buf = b''
        while count:
            newbuf = sock.recv(count)
            if not newbuf: return None
            buf += newbuf
            count -= len(newbuf)
        return buf

    # 接收图片
    def recv_all(self,sock, count):
        buf = ''
        while count:
            # 这里每次只接收一个字节的原因是增强python与C++的兼容性
            # python可以发送任意的字符串,包括乱码,但C++发送的字符中不能包含'\0',也就是字符串结束标志位
            newbuf = sock.recv(1)
            if not newbuf: return None
            buf += newbuf
            count -= len(newbuf)
        return buf

    def run(self):

# 接受TCP链接并返回(conn, addr),其中conn是新的套接字对象,可以用来接收和发送数据,addr是链接客户端的地址。
        conn, addr = self.server_socket.accept()
        while True:
            length = self.recv_size(conn,16) #首先接收来自客户端发送的大小信息
            if isinstance (length,str): #若成功接收到大小信息,进一步再接收整张图片
                stringData = self.recv_all(conn, int(length))
                data = numpy.fromstring(stringData, dtype='uint8')
                decimg=cv2.imdecode(data,1) #解码处理,返回mat图片
                cv2.imshow('SERVER',decimg)
                if cv2.waitKey(10) == 27:
                    break 
                print('Image recieved successfully!')
                conn.send("Server has recieved messages!")
            if cv2.waitKey(10) == 27:
                break 

        self.server_socket.close()
        cv2.destroyAllWindows()
    
if __name__ == '__main__':
    s = ServerSocket()
    s.run()

树莓派端

#!/usr/bin/python
#-*-coding:utf-8 -*-
import socket
import cv2
import numpy as np

host_port = ('192.168.43.227',8080)
capture_frame_width = 640
capture_frame_height = 480
class ClientSocket(object):
    def __init__(self):
        # socket.AF_INET用于服务器与服务器之间的网络通信
        # socket.SOCK_STREAM代表基于TCP的流式socket通信
        self.client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.client_socket.connect(host_port) #链接服务器
        self.capture = cv2.VideoCapture(0)
        self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, capture_frame_width)
        self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, capture_frame_height)
        self.encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90]  #设置编码参数
    def run(self):
        #从摄像头获取图片
        ret , frame = self.capture.read()
        while ret: 
            # 首先对图片进行编码,因为socket不支持直接发送图片
            result, imgencode = cv2.imencode('.jpg', frame)
            data = np.array(imgencode)
            stringData = data.tostring()
            # 首先发送图片编码后的长度
            self.client_socket.send(str(len(stringData)).ljust(16))
            # 然后一个字节一个字节发送编码的内容
            # 如果是python对python那么可以一次性发送,如果发给c++的server则必须分开发因为编码里面有字符串结束标志位,c++会截断
            for i in range (0,len(stringData)):
                self.client_socket.send(stringData[i])
            ret, frame = self.capture.read()
            #cv2.imshow('CLIENT',frame)
            # if cv2.waitKey(10) == 27:
            #     break
            # 接收server发送的返回信息
            data_r = self.client_socket.recv(50)
            print (data_r)
        self.client_socket.close()
        cv2.destroyAllWindows()
if __name__ == '__main__':
    s = ClientSocket()
    s.run()```

你可能感兴趣的:(个人项目,socket)