pythonpython-sockets

Python, socket, freezing the console before departure


I have two codes server and client. When sending an image from the client to the server, everything goes fine, but later I want to send a message to the client from the server and before sending it, the console simply freezes on both the client and the server

The code for the server:

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 5005))
server.listen()

client, addr = server.accept()
id = 4

print("w")
file = open("out.png", mode="wb")
data = client.recv(4096)
while data:
    file.write(data)
    data = client.recv(4096)
file.close()

print("ww")
client.sendall(str(id).encode('utf8'))
server.close()

The code for the client:

import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 5005))

file = open("tstop/abdul.jpg", mode="rb")
data = file.read(4096)
print("up")
while data:
    client.send(data)
    data = file.read(4096)
file.close()
print("down")

data = client.recv(2048)
print ("Received response:" + str(data.decode('utf8')))
client.close()

I used the print to understand at what point I have the code hanging I recently started studying the socket library


Solution

  • You need to somehow inform the server that no more data will be sent.

    There are several different approaches to this, the simplest of which is to do:

    client.shutdown(socket.SHUT_WR)
    

    ...on the client side once your while data: loop terminates

    You can simplify all of your code like this:

    # server
    
    import socket
    
    CHUNK = 4096
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
        server.bind(("0.0.0.0", 5006))
        server.listen()
        try:
            client, _ = server.accept()
    
            with open("out.png", mode="wb") as file:
                while data := client.recv(CHUNK):
                    file.write(data)
    
            client.sendall(b"4")
        finally:
            client.close()
    
    # client
    
    import socket
    
    CHUNK = 4096
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client:
        client.connect(("127.0.0.1", 5006))
    
        with open("tstop/abdul.jpg", mode="rb") as file:
            while data := file.read(CHUNK):
                client.send(data)
            client.shutdown(socket.SHUT_WR)
    
        data = client.recv(CHUNK)
        print ("Received response: " + data.decode())
    

    Thus, out.png will be a replica of tstop/abdul.jpg and the client code will output:

    4