Search code examples
python-3.xsocketstry-catchrecv

Receiving data only if sent python socket


I am writing a messenger application in python and I have a problem. The problem is quite simple: I want the program to only receive data from the other computer if it was sent, otherwise, my program would wait for a data transfer infinitely. How would I write that piece of code? I imagine it'd be something like this:

    try:
        data = s.recv(1024).decode()
    except:
        data == None

Solution

  • See the select module. A socket can be monitored for readability with a timeout, so other process can proceed.

    Example server:

    import socket
    import select
    
    with socket.socket() as server:
        server.bind(('',5000))
        server.listen(3)
        to_read = [server]  # add server to list of readable sockets.
        clients = {}
        while True:
            # check for a connection to the server or data ready from clients.
            # readers will be empty on timeout.
            readers,_,_ = select.select(to_read,[],[],0.5)
            for reader in readers:
                if reader is server:
                    client,address = reader.accept()
                    print('connected',address)
                    clients[client] = address # store address of client in dict
                    to_read.append(client) # add client to list of readable sockets
                else:
                    # Simplified, really need a message protocol here.
                    # For example, could receive a partial UTF-8 encoded sequence.
                    data = reader.recv(1024)
                    if not data: # No data indicates disconnect
                        print('disconnected',clients[reader])
                        to_read.remove(reader) # remove from monitoring
                        del clients[reader] # remove from dict as well
                    else:
                        print(clients[reader],data.decode())
            print('.',flush=True,end='')
    

    A simple client, assuming your IP address is 1.2.3.4.

    import socket
    s = socket.socket()
    s.connect(('1.2.3.4',5000))
    s.sendall('hello'.encode())
    s.close()