CSCI 250 Lab #3: Sockets and Threads
Part 1: Background
In this lab we will explore the final issue discussed in the first week of class, the use of sockets and threading to support remote control of a robot. Like the C++ you’re learning for Arduino, sockets and threads are a skill that you will find powerful and useful beyond their use in robotics. As with the other lab work in the course, we are going to take a team-based project and convert it to something you can do on your own in our classroom. As before, to receive full credit for this lab, your team should upload your code to your github at the end.
Part 2: Download and run client/server code
Here are downloadable copies of the client server scripts from the lecture notes: server.py client.py. As usual with client/server code, you should run the server first. If you get an ‘address already in use’, just edit both programs to use a new port number (e.g., instead of them both using 20000, they both use 20001).
Change server.py so that instead of waiting to receive client data, it simply sends out the word “hello” or some other string, in a loop. Then when you run the client, you should see this string spewing onto the screen.
To complete this part, modify the server again so that instead of sending the same arbitrary string over and over, it sends the string representation of a count. Start the count at zero, increase it on each iteration. To prevent the count from going up too fast, import time at the top of the code, and call time.sleep(.01) inside the loop.
Now for the tricky part: first, move all the code in your client.py program into a single function called updater(), and put a call to this function at the bottom. Running the program should produce the same behavior.
Next, call your updater function in a thread, as we did in the lecture notes. At the very bottom of your client program you should have an infinite loop, to keep the main program from exiting while the thread is running. As you did with the server program, use time.sleep() to slow down the loop, though here we’ll use time.sleep(1)to slow it down a lot more.
Finally, we’re going to need a way to get data in and out of our updater function. I’ve found that the simplest way to do this is to create a list of just one item; e.g., vals = , and pass it to the updater thread in the way we saw in the slides:
t = Thread(target=updater, args=(vals,)).
The updater function show now take vals as input. Instead of printing out the message, the updater function should now modify the vals list so that it contains the integer made from the string received by the server:
vals = int(msg.decode())
Now when you run the client program, you should see the numerical values reported at one-second intervals, going up by large intervals as they are modified by the higher-frequency updater thread.