'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. 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
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Steffen Ullrich |
