计算机网络代写 | CSE422 Computer Networks Fall 2020
CSE422 Computer Networks Fall 2020
Project 1: Introduction to Socket Programming
3.1 Bulls and Cows [Wikipedia Entry]
The server program holds a four-digit secret number, with no repeated digits. The client
program tries to guess the secret number by sending a four-digit guess to the server. The
server compares the guessed number and the secret number. If a matching digit is also on
the right position, it is a bull (A). If a matching digit is on different position, it is a cow
(B). The server replies to the client with the number of bulls and cows, but the client is not
told which digit is Bull and which is Cow.
For example, suppose the secret number is 7632
1. Guess: 1234, Result: 1A1B (The 3 is a bull and the 2 is a cow).
2. Guess: 5678, Result: 1A1B (The 6 is a bull and the 7 is a cow).
3. Guess: 9012, Result: 1A0B (The 2 is a bull and there are no cows).
4. and so on…
A simple implementation of the non-network aspect of Bulls and Cows game is provided in
Bulls And Cows.*.
3.2 packet.h: packet format and protocol
The packet in the project are defined as having only two fields: 1. message type: unsigned
int integer and 2. message buffer: char buffer. The protocol consists of several
message types defined in packet.h. The protocol is visualized in Figure. 1.
Figure 1: The protocol for project 1. The thick vertical lines denote processes. Note that
the server creates new processes to handle individual client. The solid/dashed lines denote
communication through a TCP/UDP socket.
3.3 The server program
Example invocation: ./proj1 server
The server program will be a multi-process program, that takes no argument. The parent
process is responsible for listening for incoming client requests and the child processes are
responsible for handling individual clients.
The parent process creates a TCP socket and waits for incoming TCP connections. This
TCP socket’s port will be assigned by the operating system and printed to the console. We
assume that the clients know this TCP port number, because the clients are started after
the server. For each incoming TCP connection, the server program creates a child process
using the system call fork(). The child process for this specific TCP connection then waits
a JOIN message from the client. The child process discards ANY message that is not JOIN,
and in this case, terminates the child process. If the incoming packet’s type is JOIN, the
child process creates a UDP socket, whose port is also assigned by the OS. Via the TCP
socket, the child process returns a packet of type JOIN GRANT and UDP port number in the
The game (guessing, responding, and exiting) is played using the UDP socket. When a client
sends a GUESS message, the server responds with the result in a RESPONSE message. If the
client has all four digits correct (four bulls), the server starts a new game until the client
enters the EXIT command. When a client sends an EXIT message, the server grants this
exit, returns an EXIT GRANT and terminates the child process for this client. If the recieved
message is not one of these expected types, then the child process terminates.
Since the server is designed to normally listen() indefinitely, it will closed by posting a
SIGINT signal against it (i.e. Ctrl-C).
In order to make sure no socket file descriptors are leaked, make sure to implement a SIGINT
handler to close open sockets and then terminate. Additionally, this will be helpfull while
developing/debugging the server.
A skeleton server code is provided: proj1 server.cc. A parse args() function is also
provided in proj1 server.h.
3.4 The client program
Example invocation: ./proj1 client -p 48192 -s localhost
The client program is required to accept the following arguments.
• -s is the server address (domain name or IP address).
• -p is the TCP port number that the server listen for incoming connection.
The client resolves the server address using gethostbyname() and connects to this server
over TCP. The client then sends a new game request JOIN to the server, in order to obtain
the UDP port number for gameplay. After the client obtains the UDP port number, a game
process is created at the server side. The player either tries to guess the secret number by
entering GUESS or exits the game by entering EXIT. As mentioned above, the server starts a
new game (generate a new secret numbe ) when the player has all four digits correct. The
client program will also output a message, showing that the player has won the game.
Note that the message JOIN is sent by the client program right after the client’s TCP
connection to the server is established. The player does NOT need to issue a JOIN command.
The player can only issue two types of commands: GUESS and EXIT. The parsing function
get command() that only accepts those two commands is provided in proj1 client.h.
Make sure to also add a SIGINT handler that properly closes all open sockets for the client
as well. Although this process is not expected to run indefinitely, it is still important to have
a clean way to terminate this process while developing/debugging.
A skeleton client code is provided: proj1 client.cc. Several helping functions, including
command parsing and argument parsing, are provided in proj1 client.h.
3.5 Error Handling
Note that many of the socket functions (socket(), bind(), etc.) can fail and return negative
values accordingly. Make sure to check each of these return values for failure before moving
on in the code. In case of failure notify the user, close sockets, and shutdown.
In addition, some functions, like recv(), can return 0 to indicate that the other connected
socket has been shutdown. This would indicate that the other process has experienced some
error and had to shutdown unexpectedly. Make sure to notify the user, close sockets, and
shutdown in this case as well.