Chapter 8
The rest value is important because we will feed it back to recv_msgs() next time
we call it, and it will be prefixed to the data from the recv() calls. In this way, the
leftover data from the last recv_msgs() call won't be lost.
So, in our preceding example, parsing the messages would take place as shown here:
recv_msgs call data argument recv result Accumulated data msgs rest
1 - 'caerphil' 'caerphil' [] b''
1 - 'ly\0illches' 'caerphilly\0illches' ['caerphilly'] 'illches'
2 'illches' 'ter\0brie\0' 'illchester\0brie\0' ['illchester',
'brie']
b''
Here, we can see that the first recv_msgs() call doesn't return after its first iteration.
It loops again because msgs is still empty. This is why the recv_msgs call numbers
are 1, 1, and 2.
A multithreaded chat server
So let's put this to use and write our chat server. Make a new file called 2.1-chat_
server-multithread.py and put the following code in it:
import threading, queue
import tincanchat
HOST = tincanchat.HOST
PORT = tincanchat.PORT
send_queues = {}
lock = threading.Lock()
def handle_client_recv(sock, addr):
""" Receive messages from client and broadcast them to
other clients until client disconnects """
rest = bytes()
while True:
try:
(msgs, rest) = tincanchat.recv_msgs(sock, rest)
except (EOFError, ConnectionError):
handle_disconnect(sock, addr)
break