Preparing for Multiple Connections
To handle multiple connections, you’ll use the selectors
module. However, you could opt to use threads. If you’d like to dive into this alternative implementation, then check out the following resources:
- 📰
asyncio
— Asynchronous I/O - 📰 Async IO in Python: A Complete Walkthrough
- 🎬 Hands-On Python 3 Concurrency With the
asyncio
Module - 📰 An Intro to Threading in Python
- 🎬 Threading in Python
While threading is certainly worth learning, it can get a bit complicated. The selectors
module helps to simplify how you handle concurrency.
00:00 So far, your programs have only made one connection and sent and received a single message. The next example will allow for multiple connections, so let’s take a look about what will be involved with that. Right now, the server can only handle a single connection, and data is limited to a single message of up to one kilobyte.
00:21
You’ll need to use the .send()
method when the size of the data to be sent isn’t immediately known. That means, however, it probably won’t be able to send all of its data in a single call, especially if the socket on the other side of the connection is limiting how much it wants to receive, as in this case, the limit was one kilobyte.
00:40
The .send()
method returns the number of bytes actually sent, which your program then needs to use to figure out what data still remains.
00:49
The simple echo example got around that by using the .sendall()
method. Since the message, "Hello, world"
, was much smaller than one thousand characters, you could send the data in a single call, knowing the other program was set to receive up to that amount of data.
01:07 To solve these problems, you’ll need to learn about concurrency, writing code for multiple things to be happening at the same time. There are two common ways to do this in Python.
01:17 The first is by using asynchronous input and output available since Python version 3.4. This approach is done by making use of threads. Using threads can be a bit complicated. However, it’s worth learning.
01:31 Python’s documentation on asynchronous I/O and Real Python’s tutorial on threads are both linked below should you be interested in studying this topic further.
01:41
For this example, however, we’re going to use the .select()
method, which can check for completed input and output on multiple sockets. It comes from the selectors
module, which helps simplify how you handle concurrency. selectors
is based on select
, which is a system-level set of functions used to handle input and output.
02:01
You’ll create a selector, put waiting sockets in it, and when any are ready to be processed, the .select()
method call will detect them and return them as a list of events for your program to respond to.
02:13 More information can be found from its Python documentation.
02:20
So how do you use .select()
? First, you’ll have to write the event loop yourself. You’ll see this is done in another while True
loop in both the server and client programs.
02:31 While it’s true that the global interpreter lock restricts what a Python program can do in parallel, since we’re using a lot of I/O, which is significantly slower than other computing tasks, the GIL limitations aren’t typically detectable.
02:46
In your next example of the echo client and server, you’ll see the .select()
method used to handle multiple connections, and you’ll see iterated use of .send()
and .recv()
.
Become a Member to join the conversation.