CSCI 250: Sockets Lab
Goal / Turnin
In yesterday's lab we learned how to use a serial connection to read data off a sensor.
The goal of today's lab is to learn how to use a socket connection. Whereas serial connections
are essential for communicating with peripheral devices – ordinary peripherals like
keyboard and mouse, as well as microcontrollers like Arduino – sockets are the basis of communication
between computers, and hence the basis of the internet itself. Every time you connect to a website, your
web browser is acting as a client, receiving data from and making requests to the server
that's providing the content you see. Indeed, sockets are so popular for communication
that they are also used for controlling, and getting video from, many robot toys: the Parrot AR.Drone and
the Brookstone Rover tank being just two examples.
In this lab you will learn how to use Python's simple sockets library to send messages between computers.
The lab will culminate with a remote sensing exercise, in which you will use your Arduino-based
sensor code from yesterday's lab to retrieve data from a sensor not directly connected to your computer.
As with yesterday's lab, you do not need to turn anything in; instead, you will demo each stage of your work to me,
and then sign the sign-out sheet before leaving.
Part 1: Talk to yourself
I have written two simple socket programs, server,py and client,py,
which your should now download (right-click / save-as) to your desktop.
Their roles match their names: the server waits for a client to connect, and then allows you
to send text messages to the client, which prints them out as it receives them. Although sockets readily support
two-way communication between a server and multiple clients, this simple
one-way communication to a single client is adequate to give you a feel for the power of sockets,
especially their use in remote sensing.
As with yesterday's lab, you will find it easier to run these programs from the command line in a terminal window.
will give you a brief instruction and example on how to use the server. As you'll see, you'll need to know your
computer's IP address to run this program. A good way to do this, that works on both Linux and Mac OS X, is to
issue the ifconfig (interface-configuration) command in your terminal window. You'll see several
paragraphs of information scroll by, with cryptic interface names like enp2s0f0, followed by a line
starting with inet, which precedes the IP address. Our IP addresses
start with 137.113.118, but it is also worthwhile looking at the other
addresses: addresses starting with 127 are reserved for “loopback”
testing between the computer and itself, and addresses starting with 192 are
for private networks, both of which you should ignore for this exercise.
Once you've got your computer's IP address, you'll also need to pick a port number on which to serve
the socket connection. (If the IP address is like a phone number, the port is like an extension). Port numbers
are arbitrary, but must be above a certain minimum, because low values are reserved for standard, always-on services
(e.g., 25 is for the SMTP service behind email). So, as the example shows, you should use a big value like 20000.
After launching the server, launch the client using the same IP address and port. You should now be able to type
messages at the server's prompt; hitting ENTER will cause the message be sent to and echoed in the client's terminal.
The operating system gives your server programs exclusive access to the port you choose, which is held for a brief
period if the program exits abnormally. So, if you have to restart the server and client, and you get a message
that the port is unavailable, just use a higher one (20001, 20002, etc.)
Part 2: Talk to your friend
As you might have guessed, the next step is to send messages between computers. Have one member of your team run
the server on one computer, and another member run the client on a different computer, with the client using
the IP address of the server computer (like making a phone call, you call someone else's number, not your own!)
Of course, you could just as easily use these programs to send messages across the world. For people who grew
up with the internet, that may not seem like a big deal, but it would be worth a few minutes of your time now
to simply look at the client and server code: with a few dozen lines of Python, you have the basis for an international
communications network! Note the use of the string encode() method by the server, and the corresponding
decode() method by the client. These methods are necessary because Python3 (unlike Python2) requires that
all transmitted messages, including strings, be sent as byte arrays, rather than strings. So, if you're ever
working with serial or socket code in Python, and you get a weird message about encodings (or something else at
the point where you're trying to send, receive, or display your data), it's probably an encoding issue resulting
from old Python code being run under Python3.
Part 3: Talk to your sensor
This is a robotics class, not a networking class, so we'll want to use our little client/server network for more than
sending text messages: we want to get sensor telemetry from a robot! So, first copy sensor.py to a new script
sensorerver.py. Then merge in your PyFirmata code from yesterday's
sensorlab.py so that instead of waiting for user input and sending it
to the client, sensorserver.py reads data from your sensor and sends
it as text messages. (You won't need any of the RealtimePlotter stuff, but you will need the pyfirmata
folder to be in the same location as sensorserver.py.)
Part 4: Go wireless!
Robots wouldn't be much fun if they had to be connected to a computer over a wire (though I'm kinda relieved that
this robot still seems to need one!) So, if we have
time at the end (and the computers are behaving), we will attempt to create an ad-hoc wifi network to
run our server – allowing us in principle to read its data using a
smartphone, tablet, or other handheld device. For a real robot, we'd run the server on an inexpensive
single-board computer like Raspberry Pi, which now comes with a wifi chip built in, for
easy ad-hoc networking.
For extra credit, merge the RealtimePlotter part of your serialsensor.py code into
client.py, so that instead of just printing out the sensor values, the client displays them
in real time.
Once you're done with all parts, please give me a demo, and have each of your team members sign the sign-out sheet to receive full credit for the lab.