Sockets are a fundamental abstraction for many types of computer communication- both inside a single machine and over networks. They are the basic primitives used to connect machines together, and they are used to implement all kinds of networked communication. Despite this, they are surprisingly simple to use, as they encapsulate and hide virtually all of the technical details need to accomplish such communication, and are accessed (like many other things in Linux) just like you were reading or writing a local file.
In this studio, you will:
Please complete the required exercises below, as well as any optional enrichment exercises that you wish to complete.
As you work through these exercises, please record your answers, and when finished email your results to email@example.com with the phrase Sockets in the subject line.
Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.
man 2 bindunder the section labeled EXAMPLE. Feel free to copy this code, but be sure to cite it.
Your server should perform the following actions:
socket(). To create a local connection use the domain
AF_UNIX), the connection type
SOCK_STREAM, and protocol zero.
bind()system call. This associates your socket from step one with a machine-visible address. In the case of
AF_LOCAL, this address is a path in the file system. Directions on how to specify a local address in this way can be found at
man 7 unix.
listen()system call. Sockets only allow one process to connect at a time, so the second parameter determines how many connection requests can wait in line before they are rejected.
accept()system call to accept a connection over the socket interface. If no connection is immediately available then this system call will, by default, cause your program block until another program attempts to connect.
accept()the connection has been established. You may read and write data over the channel with the lower level
write()system calls, or you can instantiate a stream interface with the
fdopenfunction. When doing so, be sure to use the socket descriptor returned by the call to
accept(), not the one created by the initial call to
socket(). Have your server read from the socket and print what it gets to the console.
unlink()in order to destroy the socket and connection before the program returns.
Note: Many things can go wrong with socket-based communication.
As usual, you should always check function return codes to detect errors. Recall
that most functions allow you to print a descriptive error statement with a
line of code such as:
perror("Error calling bind()").
connect()system call. This requires using the same socket address struct as the call to
At this point, barring any errors, your communcations channel is ready to be used. Send some messages to the server program and print them to standard output in order to validate the functionality. Copy and paste the server output as the answer to this exercise. Note that a call to read an empty socket will block until data is available.
accept(), but not to
bind(). Print a message each time a new connection is established and run your client program several times with the same server to validate this behavior. Copy and paste the server output as the answer to this exercise.
strncmpto test for string equality. The similar function
Copy and paste terminal output demonstrating this functionality