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

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

我在 Python 中有一个 TCP/IP 通信,其中客户端将图像发送到目标服务器。接收到图片后,返回一个响应给客户端,通知图片接收成功。我的问题是我想在客户端发送新图像时保持服务器套接字打开,因为在我的情况下一次只有 1 帧,大约每小时一次。因此,服务器套接字需要保持打开状态以侦听来自客户端的新连接,但我不知道如何以正确的方式做到这一点。

我当前接收图像并保存的代码是这样的:

发送帧的客户端:

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

从客户端接收帧的服务器:

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()

这对我来说很好用,但是如果我尝试添加一个 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()

这将给出以下错误:

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!

您不应在循环内关闭服务器套接字。否则它无法在此套接字上再次调用 accept,导致 Bad file descriptor in accept.