Link Search Menu Expand Document

Lab5: Socket programming

The goal of lab5 is to let you experience some hands-on socket programming by implementing two networking applications: a string concat application and a chat application. You will use socket programming in C.

Section 0: Getting started

  1. Click the GitHub lab5 link on Canvas homepage to create your lab5 clone on GitHub.
  2. Start your VM and open the VM’s terminal.
  3. Clone the lab5 repo to your VM:
    $ cd ~
    $ git clone git@github.com:NEU-CS3650-labs/lab5-<Your-GitHub-Username>.git lab5
    

    Note that the repo address git@github.com:... can be obtained by going to GitHub repo page (your cloned lab5), clicking the green “Code” button, then choosing “SSH”.

  4. Check contents:
    $ cd ~/lab5; ls *
    
    // you should see:
    slack.txt
    
    chat:
    Makefile        chat_client.c   chat_server.c   util.c
    
    concat:
    Makefile        concat_client.c concat_server.c util.c
    
  5. Build the concat server:
    $ cd ~/lab5/concat; make
    
    $ ./concat_server
    // you should see:
    Usage: concat_server server_port [random_seed]
    
  6. Build the chat server:
    $ cd ~/lab5/chat; make
    
    $ ./chat_server
    // you should see:
    Usage: chat_server server_port
    

Section 1: Understanding C socket programming

Socket programming.
In this lab, you will use the following socket interfaces:

function signaturedescription
int socket(int domain, int type, int protocol);socket() creates an endpoint for communication and returns a descriptor.
ssize_t send(int socket, const void *buffer, size_t length, int flags);send a message from a socket
ssize_t recv(int socket, void *buffer, size_t length, int flags);receive a message from a socket
int bind(int socket, const struct sockaddr *address, socklen_t address_len);bind() assigns a name to an unnamed socket.
int listen(int socket, int backlog);listen for connections on a socket
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);accept a connection on a socket
int connect(int socket, const struct sockaddr *address, socklen_t address_len);initiate a connection on a socket

To read more details about these functions, use $ man <func name>.

Multiplexing IOs.
To monitor multiple socket connections, people use select() to examine a set of I/O file descriptors. The file descriptors are grouped into file descriptor sets (fd_set). In particular, select() monitors three sets—readfds, writefds, and errorfds—to see if some of their descriptors are ready for reading, are ready for writing, or have an exceptional condition pending, respectively. Here is the function signature of select():

int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout);

Here is how to manipulate fd_set:

functiondescription
FD_ZERO(fd_set *set)Clear all entries from the set.
FD_SET(int fd, fd_set *set)Add fd to the set.
FD_CLR(int fd, fd_set *set)Remove fd from the set.
FD_ISSET(int fd, fd_set *set)Return true if fd is in the set.

Tutorials: Beej’s Guide to Network Programming

Here are several chapters that are useful for the lab:

Examples from CS3650 lectures

Section 2: a string concat app

Next, you will implement a string concat application. The application has one server (concat_server) and one client (concat_client). The server listens and accepts connections from the client. The client sends some string data to the server; the server concatenates another piece of data to that data and sends it back to the client. Finally, the client prints the concatenated data.

Exercise 1 implement concat_server.c and concat_client.c

  • update (04/11) There is a bug in our skeleton code (see this post). There are two ways to fix. Pick one.
    1. $ cd ~/lab5/ and run
      $ curl https://naizhengtan.github.io/24spring/labtutorials/lab5.patch | git apply
    2. OR, open file concat/util.c and edit line 27 to be str_buf[len] = '\0';
  • Go to the folder of the concat app: $ cd ~/lab5/concat
  • Read instructions in concat_client.c and implement TODOs.
  • Read instructions in concat_server.c and implement TODOs.
  • Now, test your implementation:
    $ cd ~/lab5/concat; make
    $ ./concat_server 3650
    // the sever should wait for clients
    
    // on another terminal
    $ cd ~/lab5/concat
    $ ./concat_client 3650
    // you should see:
    =<nCutvqjpranCutvqjpra>=
    =<SUbQcIoDpRSUbQcIoDpR>=
    =<MnuxGjytkLMnuxGjytkL>=
    =<T_^OiZVY`NT_^OiZVY`N>=
    =<yrrqJlPOoWyrrqJlPOoW>=
    =<`CKlQRlPL]`CKlQRlPL]>=
    =<k_CODkxY[^k_CODkxY[^>=
    =<wjWobpaqUWwjWobpaqUW>=
    =<^KiiMyAy`\^KiiMyAy`\>=
    =<\aQnpTpECQ\aQnpTpECQ>=
    
  • Notes: pay attention to possible errors; pay attention tailing \0 for strings.

Section 3: a chat app

In this exercise, you will implement a simple chat application with a server and two clients:

A (client) <---> S (server) <---> B (client)

In this example, clients A and B want to talk. They both connect to the server S. S establishes connections with both A and B, then takes data coming in from A and sends them to B and vice versa. The double-headed arrow indicates that communication can happen in both directions. (This arrangement can also be thought of as S acting as a proxy server, a common service in networking.)

In addition to forwarding data, S could also be used to inspect the traffic between A and B to ensure it doesn’t contain anything malicious. In our lab, your S should detect any bad words in the strings being transmitted and replace them with corresponding good words. The bad words are: ["virus", "worm", "malware"] and their corresponding good words are: ["groot", "hulk", "ironman"]. Note that the length of the bad word and its corresponding good word is the same. This means after the replaces the bad words with the good words, the length of the string being transmitted does not change.

Exercise 2 implement chat_server.c and chat_client.c

  • Go to the folder of the chat app: $ cd ~/lab5/chat
  • Read instructions in chat_client.c and implement TODOs.
  • Read instructions in chat_server.c and implement TODOs.
  • Now, test your implementation:
    $ cd ~/lab5/chat; make
    $ ./chat_server 3650
    // the sever should wait for clients
    
    // on another terminal, terminal I
    $ cd ~/lab5/chat
    $ ./chat_client 3650
    // the client should wait for inputs
    
    // on yet another terminal, terminal II
    $ cd ~/lab5/chat
    $ ./chat_client 3650
    // then, type in
    hello, malware
    
    // on terminal I, you should see:
    hello, ironman
    

Finally, submit your lab5

Submitting consists of three steps:

  1. Executing this checklist:
    • Fill in ~/lab5/slack.txt with (1) your name, (2) your NUID, (3) slack hours you used, and (4) acknowledgements.
    • Make sure that your code builds with no warnings.
      note: we will apply a 10% penalty to the compilation warnings you have.
    • Make sure you have added (git add) all files that you created (if any).
  2. Push your code to GitHub:

     $ cd ~/lab5
     $ git commit -am 'submit lab5'
     $ git push origin 
    
     Counting objects: ...
      ....
      To ssh://github.com/NEU-CS3650-labs/lab5-<username>.git
       7337116..ceed758  main -> main
    
  3. Actually submit your lab via Gradescope:
    • Navigate to https://www.gradescope.com/ and click on log in.
    • Select login with “School Credentials” and select “Northeastern University”.
    • Enter Northeastern SSO login information and you should be able to log in to your gradescope account.
    • Now, on Canvas, go to the CS3650 course and click on “Gradescope 1.3” from the left navigation bar. You will then be asked to accept the course invitation after which you can access the course on Gradescope.
    • On Gradescope, select the lab/assignment you wish to submit and click on “Upload Submission”.
    • You will then be asked to upload a zip file consisting of the files that the lab/assignment specifies.
      Note: you can either zip all the files within your lab folder, or zip your lab folder; its name must start with “lab5-“ (this is supposed to be your GitHub repo name, lab5-<username>). If you zip a folder named, for example, “mysubmit”, then Gradescope will complain about it and your submission might not work.
    • After uploading the zip file, the autograder will evaluate your submission and provide a score for it.
    • After the manual grading process is performed by the TAs, your final score for the lab/assignment will be released.

This completes lab5.

Acknowledgments

A python version of this lab is created by Anirudh Sivaraman. CS3650 staff ports the lab to C.