Client and Server Applications
while True:
msg = input() # Blocks
if msg == 'q':
sock.shutdown(socket.SHUT_RDWR)
sock.close()
break
try:
tincanchat.send_msg(sock, msg) # Blocks until sent
except (BrokenPipeError, ConnectionError):
break
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
print('Connected to {}:{}'.format(HOST, PORT))
# Create thread for handling user input and message sending
thread = threading.Thread(target=handle_input,
args=[sock],
daemon=True)
thread.start()
rest = bytes()
addr = sock.getsockname()
# Loop indefinitely to receive messages from server
while True:
try:
# blocks
(msgs, rest) = tincanchat.recv_msgs(sock, rest)
for msg in msgs:
print(msg)
except ConnectionError:
print('Connection to server closed')
sock.close()
break
We've updated our client to honor our new chat protocol by creating a new thread
to handle user input and send messages, while handling receiving messages in
the main thread. This allows the client to deal with the user input and receive the
messages at the same time.
Note that there's no shared state here, so we didn't have to get clever with Queues or
synchronization primitives.