I. Operation effect

Just to be clear, the title of the article I was looking for online was dealing with multiple connections. Shit, it’s all fake. Those on the net, can’t handle multiple connections asynchronously at all, can’t take the initiative to send messages to clients, pit!

Enter 1 on the server console to view the number of online users:

To send a message to a specified client:

Ii. Development ideas

The following is the server side development ideas, the client side is relatively simple not to say.

First, it is important to understand that the accept and recV methods of the socket block threads. This means that we need to open a new thread to handle both methods.

The process would look something like this:

1. Open a new thread to receive new connections (socket.accept())

2. When a new connection is created, a new thread is created to receive the connection message (socket.recv()).

3. As the console, the main thread receives user input and performs other operations

That is, the server needs to create a thread for each connection.

Server code

The code for the global section:

import socket  Import the socket module
from threading import Thread
ADDRESS = ('127.0.0.1'.8712)  # bind address
g_socket_server = None  The socket in charge of listening
g_conn_pool = []  # connection pool
Copy the code

Where g_conn_pool is used to store each client socket.

Initializing the server:

def init() :
    """ Initialize the server """
    global g_socket_server
    g_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  Create a socket object
    g_socket_server.bind(ADDRESS)
    g_socket_server.listen(5)  # maximum number of connections
    print("Server started, waiting for client to connect...")
Copy the code

The socket.listen() parameter is invalid

Receiving client connections and processing client messages:

def accept_client() :
    """ Receive new connections """
    while True:
        client, _ = g_socket_server.accept()  Block, waiting for the client to connect
        Join the connection pool
        g_conn_pool.append(client)
        Create a separate thread for each client to manage
        thread = Thread(target=message_handle, args=(client,))
        Set to daemon thread
        thread.setDaemon(True)
        thread.start()
 
 
def message_handle(client) :
    """ message processing """
    client.sendall("Server connection successful!".encode(encoding='utf8'))
    while True:
        bytes = client.recv(1024)
        print("Client message :".bytes.decode(encoding='utf8'))
        if len(bytes) = =0:
            client.close()
            # delete connection
            g_conn_pool.remove(client)
            print("A client is offline.")
            break
Copy the code

The purpose of setting the daemon thread is to prevent the application process from not exiting after the main thread exits.

In message processing, if a packet of length 0 is received, the client is disconnected. In actual development, we usually use the heartbeat packet mechanism to determine whether the client is online.

 

Finally, call these methods to get the server started:

if __name__ == '__main__':
    init()
    Open a thread to receive new connections
    thread = Thread(target=accept_client)
    thread.setDaemon(True)
    thread.start()
    Main thread logic
    while True:
        cmd = input("" "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - enter 1: view the current line number input 2: to specify the client sends the message input 3: shut down the server "" ")
        if cmd == '1':
            print("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -")
            print("Number of current online users:".len(g_conn_pool))
        elif cmd == '2':
            print("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -")
            index, msg = input("Please enter the form" index, message ":).split(",")
            g_conn_pool[int(index)].sendall(msg.encode(encoding='utf8'))
        elif cmd == '3':
            exit()
Copy the code

If you’re not clear about the process, go back to the second part of the article.

Iv. Client code

The client part of the design is very simple.

import socket  Import the socket module
 
s = socket.socket()  Create a socket object
s.connect(('127.0.0.1'.8712))
print(s.recv(1024).decode(encoding='utf8'))
s.send("Connected".encode('utf8'))
print(s.recv(1024).decode(encoding='utf8'))
input("")
Copy the code

The final input is used to block the thread, preventing the program from exiting after receiving the message.

Five. Write it in the back

This article does not deal with TCP sticky packets and subcontracting, and asynchronous message processing is done in a simple and crude multithreaded manner. In short, network programming learning is still a long way to go oh, this article only as a reference for entry.