如何正确关闭正在播放网络摄像头素材的套接字?

时间:2019-02-13 18:32:12

标签: python-3.x sockets network-programming cv2

我正在尝试将便携式计算机的网络摄像头流传输到我的PC上以进行cv2操作。该流有效,但是我不确定如何关闭套接字。

我的台式机上没有网络摄像头,因此我想尝试流式传输笔记本电脑网络摄像头以学习素材中的cv2。我是套接字的新手,我仔细阅读了文档,并做了很多谷歌搜索,以使事情变得更糟,即使我现在拥有的大多数内容都是复制粘贴的。我真的不确定在哪里寻找如何使用cv2流式传输视频数据时如何正确关闭套接字。 我尝试将socket.socket(...)与s一起使用:关闭连接 在while和try循环后中断,然后进入shutdown(socket.SHUT_WR和close(),我尝试终止客户端和服务器上的程序。

    #server.py

    import socket
    import cv2
    import pickle
    import struct
    def main():
        HOST=''
        PORT=12397    
        with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
            print('Socket created')
            s.bind((HOST,PORT))
            print('Socket bind complete')
            s.listen(10)
            print('Socket now listening')
            conn,addr=s.accept()

            data = b""
            payload_size = struct.calcsize(">L")
            while True:
                try:
                    key = cv2.waitKey(20) & 0xFF
                    while len(data) < payload_size:
                        data += conn.recv(4096)
                        if key == ord("q"):
                            print("Socket closed.")
                            break
                    packed_msg_size = data[:payload_size]
                    data = data[payload_size:]
                    msg_size = struct.unpack(">L", packed_msg_size)[0]
                    while len(data) < msg_size:
                        data += conn.recv(4096)
                        if key == ord("q"):
                            print("Socket closed.")
                            break
                    frame_data = data[:msg_size]
                    data = data[msg_size:]

                    frame=pickle.loads(frame_data, fix_imports=True, encoding="bytes")
                    frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
                    cv2.imshow('ImageWindow',frame)
                    cv2.waitKey(1)
                    if key == ord("q"):
                        print("Socket closed.")
                        break
                except:
                    cv2.destroyAllWindows()
                    break

        s.shutdown(socket.SHUT_WR)
        s.close()
    if __name__ == "__main__":
        main()

    #client.py

    import socket
    import cv2
    import pickle
    import struct
    def main():
        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
        with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as client_socket:
            print('Connecting to socket.')
            client_socket.connect((ENTER IP HERE, 12397))
            connection = client_socket.makefile('wb')
            print('Starting stream.')
            cam = cv2.VideoCapture(0)
            cam.set(3, 320*2);
            cam.set(4, 240*2);
            frame_time = int((1.0 / 30.0) * 1000.0)
            img_counter = 0
            while True:
                try:
                    ret, frame = cam.read()
                    if ret:
                        result, frame = cv2.imencode('.jpg', frame, encode_param)
                        data = pickle.dumps(frame, 0)
                        size = len(data)
                        client_socket.sendall(struct.pack(">L", size) + data)
                        img_counter += 1
                        if cv2.waitKey(frame_time) & 0xFF == ord('q'):
                            break
                    else:
                        break
                except KeyboardInterrupt:
                    break
        cam.release()
        client_socket.shutdown(socket.SHUT_WR)
        client_socket.close()
    if __name__ == "__main__":
        main()

我想按q关闭连接。 我目前在服务器上收到WinErrors OSError:[WinError 10038]尝试对非套接字的对象进行操作 和在客户端上 ConnectionResetError:[WinError 10054]现有连接被远程主机强行关闭 当我在服务器端(垃圾邮件)“ q”时,如果只按一次它似乎并没有发现问题。

1 个答案:

答案 0 :(得分:0)

如果您在关闭插座后使用插座 ,通常会发生该错误。

现在,如果我们使用您的服务器,您将执行类似的操作

with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
    ... code here ...

s.shutdown(socket.SHUT_WR)
s.close()

这意味着{}和shutdown调用在套接字已关闭后 完成。

您在客户端程序中遇到相同的问题。