简体   繁体   English

Python Sockets - 在完成接收数据后保持服务器套接字活动

[英]Python Sockets - Keeping server socket alive after it's done receiving data

I have a TCP/IP communication in Python where the client sends the image to the destination that is the server.我在 Python 中有一个 TCP/IP 通信,客户端将图像发送到目标服务器。 After receiving the image is received, a response is sent back to the client informing that the image has been successfully received.接收到图片后,返回一个响应给客户端,通知图片接收成功。 My problem is that I would like to keep the server socket open for when a new image is sent by the client, given that in my situation only 1 frame at once, every hour or so.我的问题是我想在客户端发送新图像时保持服务器套接字打开,因为在我的情况下一次只有 1 帧,大约每小时一次。 Thus, the server socket needs to remain open to listen for a new connection from the client, but I can't figure out how to do it the right way.因此,服务器套接字需要保持打开状态以侦听来自客户端的新连接,但我不知道如何以正确的方式进行。

My current code that receives an image and save is this:我当前接收图像并保存的代码是这样的:

Client that sends a frame:发送帧的客户端:

import numpy as np
import cv2
from PIL import Image
import base64
import socket
from os.path import dirname, join
from com.chaquo.python import Python

def main(data):
    s = socket.socket()
    s.connect(("192.168.0.16", 9999))

    decoded_data = base64.b64decode(data)

    files_dir = str(Python.getPlatform().getApplication().getFilesDir())
    filename = join(dirname(files_dir), 'image.PNG')

    out_file = open(filename, 'wb')
    out_file.write(decoded_data)



    filetosend = open(filename, "rb")
    data = filetosend.read(512)
    while data:
        print("Sending...")
        s.send(data)
        data = filetosend.read(512)
    filetosend.close()
    s.send(b"DONE")
    print("Done Sending.")
    msg = s.recv(512).decode()
    print(msg)
    s.shutdown(2)
    s.close()

    return msg

Server that receives a frame from the client:从客户端接收帧的服务器:

import socket
import cv2
import numpy as np
import os
import uuid

img_dir = '/home/pi/Desktop/frames_saved/'
img_format = '.png'
filename = str(uuid.uuid4())
s = socket.socket()
s.bind(("192.168.0.16", 9999))
s.listen(1)
c,a = s.accept()
filetodown = open(img_dir+filename+img_format, "wb")
while True:
   print("Receiving....")
   data = c.recv(512)
   print(data)
   if b"DONE" in data:
       print("Done Receiving.")
       break
   filetodown.write(data)
filetodown.close()
c.send("Thank you for connecting.".encode())
c.shutdown(2)
c.close()
s.close()

This works fine for me, however if I attempt to add a while loop to keep the socket open, like this:这对我来说很好,但是如果我尝试添加一个 while 循环来保持套接字打开,如下所示:

import socket
import cv2
import numpy as np
import os
import uuid


filename = str(uuid.uuid4())
s = socket.socket()
s.bind(("192.168.0.16", 9999))
s.listen(1)
while True:
    c,a = s.accept()
    img_dir = '/home/pi/Desktop/frames_saved/'
    img_format = '.png'
    filetodown = open(img_dir+filename+img_format, "wb")
    while True:
       print("Receiving....")
       data = c.recv(512)
       print(data)
       if b"DONE" in data:
           print("Done Receiving.")
           break
       filetodown.write(data)
    filetodown.close()
    c.send("Thank you for connecting.".encode())
    c.shutdown(2)
    c.close()
    s.close()

This will give the following error:这将给出以下错误:

Traceback (most recent call last):
  File "server.py", line 13, in <module>
    c,a = s.accept()
  File "/usr/lib/python3.7/socket.py", line 212, in accept
    fd, addr = self._accept()
OSError: [Errno 9] Bad file descriptor
s.listen(1)
while True:
    c,a = s.accept()
    ...
    c.close()
    s.close()                   <<<< WRONG!

You should not close the server socket inside the loop.您不应在循环内关闭服务器套接字。 Otherwise it cannot call accept again on this socket, leading to Bad file descriptor in accept .否则它不能在此套接字上再次调用accept ,导致accept中的Bad file descriptor

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM