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

Time:04-08

I have a TCP/IP communication in Python where the client sends the image to the destination that is the server. 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. 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:

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

CodePudding user response:

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.

  • Related