How to receive multiple socket requests on a single server?

5

Hello! I'm doing a server / client schema program in Python where I wanted to have only one server and multiple clients.

Let's say we have 3 clients each making a request to the server per socket connection, how is it that:

  • 1: Could the server accept more than one socket connection at a time?

  • 2: The server would perform the tasks (it had thought of a database to store the requests and serve as cache)

Thank you!

    
asked by anonymous 19.02.2017 / 00:16

1 answer

6

The answer to your first point is "yes", the server can accept and process more than one connection we have to prepare it for it.

In this example the server can handle a single connection, but by grasping this we can implement support for multiple connections, we will have to implement threads , where each connection on the server is a thread / processo "independent".

Below is a simple example of a chat server, commented on where I think it should be explained:

Server:

import socket, threading

def run(conn):
    while True:
        data = conn.recv(1024) # receber informacao
        if not data: # se o cliente tiver desligado
            conns.remove(conn)
            break
        for c in conns: # enviar mensagem para todos os outros clientes
            if c is not conn: # excepto para o que a enviou 
                c.send('{}: {}'.format(conn.getpeername(), data.decode()).encode('utf-8'))

conns = set() # armazenar conxoes aqui
host, port = ('', 9999)
with socket.socket() as sock: # ligacao TCP
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reutilizar endereco logo a seguir a fechar o servidor
    sock.bind((host, port))
    sock.listen(5) # servidor ativo
    print('Server started at {}:{}\n'.format(host, port))
    while True:
        conn, addr = sock.accept() # esperar que alguem se conect
        conn.send('WELCOME {}'.format(addr).encode())
        conns.add(conn) # adicionar conexao ao nosso set de coneccoes
        threading.Thread(target=run, args=(conn,)).start() # esta coneccao vai ser independente das outra a partir de agora, vamos correr a thread na funcao run

Client:

import socket, threading, sys, select

with socket.socket() as s:
    s.connect(('', 9999))
    while True:
        io_list = [sys.stdin, s]
        ready_to_read,ready_to_write,in_error = select.select(io_list , [], [])
        for io in ready_to_read:
            if io is s: # se tivermos recebido mensagem
                resp = s.recv(1024)
                if not resp:
                    print('server shutdown')
                    sys.exit()
                print('{}'.format(resp.decode()))
            else:
                msg = sys.stdin.readline() # vamos enviar mensagem
                s.send(msg.encode())
                sys.stdout.flush()

As for your point 2 also, although you do not really understand what you want to keep in the database.

In case you want to save the connections you can for example (in this example I'll save it in a file), add this below the last line ( threading.Thread(... ) of the server example I put above:

...
with open('conns.txt', 'a') as f:
    f.write('{}\n'.format(':'.join(addr)))
    
19.02.2017 / 11:47