I have implemented a socket server and client using python. Idea is to simply send an image from client to server and get back a text message from the server. The client will select an image file (.jpg) from file system and send to server. The server would receive it and save it with a different name (current date time stamp) and send back a processed text message. The image is sent and saved successfully at the server side but the issue is that client hangs when .recv()
method is called to get message from server.
Following is the code
Server
import socket
import datetime
import time
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1",12345))
server.listen()
print("Server started and listening at port 12345")
BUFFER_SIZE=4096
while True:
client_socket, address = server.accept();
# client_socket.setblocking(False)
print(f"Connection from {address} has been established.")
file_name = str(datetime.datetime.now()).replace(" ", "").replace(":", "-")
file_name = file_name ".jpg"
with open(file_name, "wb") as file:
recv_data = client_socket.recv(BUFFER_SIZE)
while (recv_data):
file.write(recv_data)
recv_data = client_socket.recv(BUFFER_SIZE)
print("File writing done, preapring data to send...")
client_socket.send(bytes("Hey there!!!", "utf-8"))
client_socket.close()
Client
import socket
import threading
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 12345))
BUFFER_SIZE = 4096
with open("client_file.jpg", 'rb') as file:
file_data = file.read(BUFFER_SIZE)
while (file_data):
client.send(file_data)
file_data = file.read(BUFFER_SIZE)
msg = client.recv(1024) # <-------[[[ hangs here ]]]
print(msg.decode("utf-8"))
CodePudding user response:
There is a deadlock since both client and server are each waiting for the other to send data. The server is reading the input until end of stream: client_socket.recv
in server will hang if the connection is still open but the client is not sending more data. At the same time the client is waiting for the server to send something, i.e. client.recv
is hanging.
There seems to be an assumption that client_socket.recv
will return with no data once the client is done sending. This is not the case. It will only return if the client has shutdown the connection or if new data are available. The common way to handle this is to have some information when the transfer is done, like prefixing the transfer with the size or doing a one-sided shutdown.
CodePudding user response:
you need to client.shutdown(socket.SHUT_WR)
after sending the image, to tell the server that you finished sending. It will work like a breeze after that