CS 779/879
Design of Network Protocols
Spring 2011
Second Exam
Time 2 & 1/2 hours
Open Book
Name:
Login:
All questions are of equal weights.
Question 1:
A. Sometimes we may use read/write
with a UDP socket. Give an example.
B. Sometimes we have to use send/recv with a TCP socket. Give an example.
Question 2:
Suppose we want to implement a general chat server (GCS) that allows the user to use the following types of chat clients:
TCP, UDP (Unicast or Multicast) and SCTP (Stream or Sequence Packets) each can use either IPV4 or IPV6.
What is the maximum possible number of different types of chat clients can be used?
What is the minimum possible number of server sockets needed to implement the GCS?
Explain briefly how the server is going to switch the chat messages among all participating clients.
Question 3:
The following are several possible
implementations of a chat client: f, t, s, n, b1 and b2.
Assuming all chatters will use the same
implementation; describe which of these implementations will:
1. Perfectly perform its function. Do not explain..
2. Poorly perform its function. Explain why?
3. Fail to perform its function. Explain
why?
GeneralChatClient.c
int sockfd;
int main(int argc, char **argv)
{
int pid;
struct sockaddr_in servaddr;
struct hostent *hp, *gethostbyname();
sockfd =
socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
hp = gethostbyname(argv[1]);
bcopy(hp->h_addr, &(servaddr.sin_addr.s_addr),
hp->h_length);
servaddr.sin_family
= AF_INET;
servaddr.sin_port
= htons(atoi(argv[2]));
if (connect(sockfd,(SA*)&servaddr,sizeof(servaddr))<0)
exit(-1);
if (strcmp(argv[3], "f") == 0) Chat_fork();
else if (strcmp(argv[3], "t") == 0) Chat_thread();
else if (strcmp(argv[3], "s") == 0) Chat_select();
else if (strcmp(argv[3], "n") == 0) Chat_nonblock();
else if (strcmp(argv[3], "b1") == 0) Chat_block1();
else if (strcmp(argv[3], "b2") == 0) Chat_block2();
}
int Chat_fork()
{
int pid =
fork();
if (pid ==
0) {
HandleSocket();
kill(getppid(),
9);
} else {
HandleStdin();
kill(pid,
9);
}
}
int Chat_thread()
{
pthread_t tid1;
pthread_t tid2;
pthread_create(&tid1,
NULL, &HandleSocket, NULL);
pthread_create(&tid1,
NULL, &HandleStdin, NULL);
pthread_join(tid1,
NULL);
pthread_join(tid2,
NULL);
}
int Chat_select()
{
fd_set readset;
int nread;
char buffer[512];
for (;;) {
FD_SET(sockfd,
&readset);
FD_SET(0, &readset);
select(4, &readset, NULL, NULL, NULL);
if (FD_ISSET(sockfd, &readset)) {
nread
= read(sockfd, buffer, 512);
if (nread
<= 0) return (0);
write(1, buffer, nread);
}
if (FD_ISSET(0, &readset)) {
nread
= read(0, buffer, 512);
if (nread
<= 0) return (0);
write(sockfd,
buffer, nread);
}
}
}
int Chat_nonblock()
{
int nread, valu;
char buffer[512];
val = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, val | O_NONBLOCK);
val = fcntl(0, F_GETFL, 0);
fcntl(0,
F_SETFL, val | O_NONBLOCK);
for (;;) {
nread
= read(sockfd, buffer, 512);
if (nread
== 0) return (0);
else if (nread
> 0) write(1, buffer, nread);
nread
= read(0, buffer, 512);
if (nread
== 0) return (0);
else if (nread
> 0) write(sockfd, buffer, nread);
usleep(100000);
}
}
int Chat_block1()
{
int nread;
char buffer[512];
for (;;) {
nread
= read(0, buffer, 512);
if (nread
== 0) return (0);
else if (nread
> 0) write(sockfd, buffer, nread);
nread
= read(sockfd, buffer, 512);
if (nread
== 0) return (0);
else if (nread
> 0) write(1, buffer, nread);
}
}
int Chat_block2()
{
int nread;
char buffer[512];
for (;;) {
nread
= read(sockfd, buffer, 512);
if (nread
== 0) return (0);
else if (nread
> 0) write(1, buffer, nread);
nread
= read(0, buffer, 512);
if (nread
== 0) return (0);
else if (nread
> 0) write(sockfd, buffer, nread);
}
}
int HandleSocket()
{
int nread;
char buffer[512];
for (;;) {
nread
= read(sockfd, buffer, 512);
if (nread
== 0) return (0);
write(1, buffer, nread);
}
}
int HandleStdin()
{
int nread;
char buffer[512];
for (;;) {
nread
= read(0, buffer, 512);
if (nread
== 0) return (0);
write(sockfd,
buffer, nread);
}
}
Question 4:
The following is a ChatClient
code.
Modify this code to send and receive Out-of-Band data
as described below:
§ Any message M typed by the user that starts with the specail character ‘^’ is sent to the
server as Out-of-Band data.
§ Any message M received from the server as Out-of-Band data is displayed to the user preceeded with the special character ‘!’
The client may use this mechanism to send and
receive non-chat information with the Chat Server.
For example, the client may use it to request the Server to
send back the list of current chat
participants.
int sockfd;
int
main(int argc, char **argv)
{
struct sockaddr_in servaddr;
struct hostent *hp, *gethostbyname();
sockfd
= socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
hp = gethostbyname(argv[1]);
bcopy(hp->h_addr, &(servaddr.sin_addr.s_addr),
hp->h_length);
servaddr.sin_family
= AF_INET;
servaddr.sin_port
= htons(atoi(argv[2]));
if(connect(sockfd,(SA*)&servaddr,sizeof(servaddr))<0)exit(-1);
Chat_thread();
}
int Chat_thread()
{
pthread_t tid1;
pthread_t tid2;
pthread_create(&tid1,
NULL, &HandleSocket, NULL);
pthread_create(&tid1,
NULL, &HandleStdin, NULL);
pthread_join(tid1,
NULL);
pthread_join(tid2,
NULL);
}
int HandleStdin()
{
int nread;
char buffer[512];
for (;;) {
nread = read(0, buffer, 512);
if (nread
== 0) return(0);
write(sockfd, buffer, nread);
}
}
int HandleSocket()
{
int nread;
char buffer[512];
for (;;) {
nread
= read(sockfd, buffer, 512);
if (nread
== 0) return(0);
write(1, buffer, nread);
}
}
Question 5:
The
following is the code for a pre-threaded echo server.
Modify
this code so that when
all the pre-threads are busy, the program will create temporary on-demand threads.
int len, listenfd;
struct sockaddr_in servaddr, cliaddr;
int
NThreads;
int
Available;
int
PortNumber;
int
main(int argc, char *argv[])
{
NThreads = atoi(argv[1]);
PortNumber
= atoi(argv[2]);
listenfd =
socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family
= AF_INET;
servaddr.sin_addr.s_addr
= htonl(INADDR_ANY);
servaddr.sin_port
= htons(PortNumber);
if (bind(listenfd,(SA*)&servaddr,sizeof(servaddr))<0)exit(-1);
listen(listenfd,
0);
Available = NThreads;
for (i = 1;
i <= NThreads; i++) {
pthread_create(NULL,
NULL, &EchoToClient, NULL);
}
pause();
}
void *EchoToClient()
{
int nread;
char buffer[512];
int connfd;
for (;;) {
len = sizeof(cliaddr);
connfd
= accept(listenfd, (SA *) & cliaddr,
&len);
--Available;
for (;;) {
nread
= read(connfd, buffer, sizeof(buffer));
if (nread
== 0) {
++Available;
break;
}
write(connfd,
buffer, nread);
}
}
}