Read the following Unix man pages: socket(2), bind(2), listen(2). accept(2), connect(2), fork(2).
What happens if you attempt to connect to the daytime port of www.stanford.edu?
Can you justify the round-trip times to each of these hosts by considering just the speed of light? Compare (approximate) distances to delays.
Note that the program will not compile on uhunix, which does not have a C compiler. Send mail to sunx@hawaii.edu to obtain an account on the ICS Unix workstations, including your full name and the fact that you need an account for ICS 451.
Also note that you are welcome to do exercises 2 and 3 on winsock instead of Unix if you prefer. If you use winsock, you will have to figure out for yourself how to write a client and a server.
/* client.c: program to connect to server. */
/* compile with: gcc -o client client.c -lsocket -lnsl */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define portnumber 4321
#define BUFSIZE 1000
#define error(s) { perror(s); exit(1); }
main ()
{
int s;
struct protoent * protocolentry;
struct hostent * hostentry;
struct sockaddr_in sin;
struct sockaddr * sap = (struct sockaddr *) &sin;
char buf[BUFSIZE];
if ((protocolentry = getprotobyname("tcp")) == NULL)
error("getprotobyname");
if ((s = socket(AF_INET, SOCK_STREAM, protocolentry->p_proto)) < 0)
error("socket");
hostentry = gethostbyname("maru.ics.hawaii.edu");
if ((hostentry == NULL) || (hostentry->h_addr_list == NULL))
error("gethostbyname");
bzero (&sin, sizeof (sin));
sin.sin_family = AF_INET;
bcopy(hostentry->h_addr_list[0], &(sin.sin_addr), hostentry->h_length);
sin.sin_port = htons(portnumber);
if (connect(s, sap, sizeof(sin)) < 0) error("connect");
printf ("enter your e-mail address and your name: ");
fgets (buf, BUFSIZE, stdin);
if (write(s, buf, strlen(buf)) < 0) error("write");
if (close(s) < 0) error("close");
}
This program contacts a server running on the machine "maru" and
gives it your name and email. These will be recorded automatically
for grading.
For all of exercise 2, the only thing you need to report is the total time and the time per connection from exercise 2.d.
If you have trouble running the server, try using a different port number (someone else may be using the same port number as you).
Make sure you have killed your server when you are done. On the suns,
use "ps -U yourlogin" to see what processes are still running.
Computer Networks, ICS 451
/* server.c: program to accept input from clients. */
/* compile with: gcc -o server server.c -lsocket */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#define portnumber 4321
#define BUFSIZE 1000
#define error(s) { perror(s); exit(1); }
main ()
{
int passive, session;
struct sockaddr_in sin;
struct sockaddr * sap = (struct sockaddr *) &sin;
struct sigaction siga;
int count, i = 0, pos = 0;
char buf[BUFSIZE] = "";
if ((passive = socket(AF_INET, SOCK_STREAM, 0)) < 0) error("socket");
bzero (&sin, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(portnumber);
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(passive, sap, sizeof (sin)) != 0) error("bind");
/* make sure child processes are really detached (see exit(2)) */
signal(SIGCHLD, SIG_IGN);
/* specify the maximum queue length */
if(listen(passive, 5) < 0) error("listen");
count = sizeof (sin);
while ((session = accept(passive, sap, &count)) >= 0) {
if (fork() == 0) { /* child process */
count = read(session, buf, BUFSIZE - 1);
buf[count] = '\0';
pos = count - 1;
if (buf[pos] == '\n') pos--;
for (i = 0; i <= pos; ) { /* reverse string */
int swap = buf[i];
buf[i++] = buf[pos];
buf[pos--] = swap;
}
if (write(session, buf, count) < 0) error("write");
if (close(session) < 0) error("child close");
exit(0);
} else { /* parent process */
if (close(session) < 0) error("parent close");
}
}
}
3.b Bind
Note what happens if you try to run a second server while the first is
still running. The operating system marks the port "in use" so that
only one server can use it at a time. If a connection has been
opened, the operating system may mark the port "in use" for a few minutes
after the server is gone.
3.c Turn in
You do not need to turn anything in for Exercise 3 -- it will serve as
a basis for project 1.
Instructor: Edo Biagioni