user7037923
user7037923

Reputation:

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

Upvotes: 0

Views: 1528

Answers (1)

Mark Tolonen
Mark Tolonen

Reputation: 177891

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()

Upvotes: 1

Related Questions