Creating a Multi-Connection Client
00:00 In this lesson, you’ll see the client that will connect to the echo server created in the last lesson. Having seen how to use a selector for managing sockets, what the client needs to do to create the socket to connect to the server shouldn’t be all that surprising.
00:15
The code is contained in multiconn-client.py
. As you can see, it’s importing the same modules as a server and creating a default type selector. Here also, you can see that the client will be sending two messages, message 1 from client and message 2 from client.
00:33 You’ll look for those to be echoed back from the server.
00:39 There’s a new aspect to this version of the client. On the command line, as well as indicating the host and port, you also specify the number of connections you would like the client to make.
00:50 For each connection, the client will create a socket and send the two messages through it. Again, you can see the socket being created using version four addresses and TCP socket streams. Like the multiconnection server, you don’t want this socket to block.
01:08
This version of the client will use the .connect_ex()
method instead of the .connect()
method that the simple version used. This one returns errors instead of raising exceptions if problems arise.
01:19 It’s the preferred one to use when taking concurrency into account.
01:24 The client will keep a slightly more complicated data object with the socket when it’s registered to the selector: its connection ID number, the total number of bytes to be sent, a running total of how many bytes it’s received, a local copy of the messages being sent, and a string to store the data being received. Then each socket is registered to the selector.
01:52 Now consider phase three, exchanging data. Both the server and the client send data to the other, but there’s a slight difference in the ordering and what each one does with the data it receives. The server first reads, saving the message, then writes, sending back the message.
02:11 However, the client first writes, sending the message it wrote, then reads, displaying the message that was echoed back.
02:22 So the structure of the client’s service connection function should be roughly the same. The only difference is in what order the reading and writing has done and what happens in each part.
02:37 If there is data received, print it, adding its size to the running total of bytes received. If there was no data sent or if it’s received the entire message back, then it’s safe to close the socket and remove it from the selector.
02:54
When writing, if there’s nothing in the data outb
string, the program gets the next item from the message list. Then once that data is designated for output, the client sends that message to the server. And just like in the server, the client records how many bytes were actually set and uses the slice operation to remove those from the outb
string.
03:18
The client’s event loop will also be slightly different from the server’s. It has a different ending condition, and that’s if all the sockets created at the beginning of the program have been processed. In that case, the selector will be empty, and sel.get_map()
will be empty, giving a falsy value.
03:38
We don’t want the selector to block completely. Otherwise, it will never get to that check. So the call to .select()
will block for up to one second in case it is empty.
Become a Member to join the conversation.