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
.