Everyone:
Next week, we will discuss system calls involving networking. We will explore using sockets to communicate between clients and servers and eventually create our own HTTP server in the form of spidey.
The focus of this reading is to explore system calls related to network sockets in C.
The readings for Monday, April 23 are:
Beej's Guide to Network Programming
You can skip the parts about datagram sockets and slightly advanced techniques.
This has basic coverage of networking, along with some information about remote procedure calls (RPC) that you can skip.
Learn Socket Programming in C from Scratch
This is free online course from Udemy that covers most of the same things we will in class. Moreover, they also cover building a HTTP server as well.
Let’s Build A Web Server. Part 1, Part 2, and Part 3
This is a series of articles that describe how to build a HTTP server in Python. It has much more information than you need for Project 02, but it provides a lot of illustrations and explanations. Read this to get an idea of what you will be doing, but don't get bogged down by the details.
This week, the reading is split into two sections: the first part is a
dredd quiz, while the second part involves one C program: ncat.c
.
To test the C program, you will need to download the Makefile and test scripts:
$ git checkout master # Make sure we are in master branch $ git pull --rebase # Make sure we are up-to-date with GitLab $ git checkout -b reading12 # Create reading12 branch and check it out $ mkdir reading12 # Create reading12 folder $ cd reading12 # Go into reading12 folder # Download Reading 12 Makefile $ curl -LO https://gitlab.com/nd-cse-20289-sp18/cse-20289-sp18-assignments/raw/master/reading12/Makefile # Download, build, and execute tests $ make test
Record the answers to the following Reading 12 Quiz questions in your
reading12
branch:
For the second part of this reading, you are to Write the C equivalent,
ncat.c
, to the Python code below (ncat.py):
#!/usr/bin/env python3 import socket import sys # Parse command line options try: HOST = sys.argv[1] PORT = int(sys.argv[2]) except IndexError: print("Usage: {} HOST PORT".format(sys.argv[0]), file=sys.stderr) sys.exit(1) # Create socket and connect to specified HOST and PORT try: csocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) csocket.connect((HOST, PORT)) cstream = csocket.makefile('w') except socket.error as e: print('Socket Error: {}'.format(e)) sys.exit(1) # Read from stdin and write to socket for line in sys.stdin: cstream.write(line) # Cleanup csocket.close()
This is basically a partial implementation of the nc command you have used
previously: given a HOST
and PORT
, the program creates a socket,
connects to the server, and then sends data from standard input to the
remote server via the socket connection.
Update the Makefile such that it contains a rule that builds the ncat
program:
$ make # Build walk program gcc -g -gdwarf-2 -Wall -Werror -std=gnu99 -o ncat ncat.c $ ./ncat # Usage Usage: ./ncat HOST PORT $ nc -l -p 9123 & # Start netcat server in background [1] 12532 $ date | ./ncat localhost 9123 # Send message to server Connected to localhost:9123 Sun Apr 15 16:50:38 EDT 2018 [1]+ Done nc -l -p 9123 $ ./ncat fakehost 9999 Could not look up fakehost:9999: Name or service not known $ ./ncat localhost 0 Unable to connect to localhost:0: Connection refused $ make clean # Cleanup rm -f ncat
Your program must:
Utilize networking system calls such as socket, getaddrinfo, and connect.
Compile with no warnings (be sure to have -Wall
in your CFLAGS
).
Not contain any memory errors (as reported by [valgrind]).
Check if system calls fail (when appropriate).
Print Connected to HOST:PORT
when a connection succeeds. If
getaddrinfo fails, then you must display: Could not look up HOST:PORT:
REASON
where REASON
is the string returned by gai_strerror. Likewise,
if you cannot connect, you must display Unable to connect to HOST:PORT:
REASON
where REASON
is the string returned by strerror. Of course,
HOST
and PORT
are the command-line arguments specified by the user.
Your code should resemble the Simple Stream Client from your reading (or the echo_client from the Lecture 22 sample code).
To submit you work, follow the same process outlined in Reading 01:
$ git checkout master # Make sure we are in master branch $ git pull --rebase # Make sure we are up-to-date with GitLab $ git checkout -b reading12 # Create reading12 branch and check it out $ mkdir reading12 # Create reading12 folder $ cd reading12 # Go into reading12 folder $ $EDITOR answers.json # Edit your answers.json file $ ../.scripts/submit.py # Check reading12 quiz Submitting reading12 assignment ... Submitting reading12 quiz ... Q1 0.25 Q2 0.75 Score 1.00 $ git add answers.json # Add answers.json to staging area $ git commit -m "Reading 12: Quiz" # Commit work $ $EDITOR ncat.c # Edit source code $ make test # Build and Run tests Testing ncat ... ncat (syscalls) ... Success ncat (usage, output) ... Success ncat (usage, valgrind) ... Success ncat (fakehost 9999, client) ... Success ncat (fakehost 9999, valgrind) ... Success ncat (localhost 0, client) ... Success ncat (localhost 0, valgrind) ... Success ncat (localhost 9770, client) ... Success ncat (localhost 9770, server) ... Success ncat (localhost 9770, valgrind) ... Success ncat (weasel.h4x0r.space 9110, client) ... Success ncat (weasel.h4x0r.space 9110, server) ... Success ncat (weasel.h4x0r.space 9110, valgrind) ... Success Score 3.00 $ git add Makefile # Add Makefile to staging area $ git add ncat.c # Add source code to staging area $ git commit -m "Reading 12: Code" # Commit work $ git push -u origin reading12 # Push branch to GitLab
Remember to create a merge request and assign the appropriate TA from the Reading 12 TA List.