Name:
Login:
NOTE: In order to make the programs short, you may NOT write any include, comments or non-essential error statements.
1
Question 1: (30 points)
1.
Write a client program Q1C that test each tcp privileged port P on any given host and displays the message: “there is a tcp server running at port P ” if it can connect to port P . The host is specified as a commandline argument. E.g.,
% Q1C 128.82.4.7
Solution ( Q1C Code C or Java)
2
2.
What are the possible reasons that you cannot connect to a port P ?
Solution
3
Question 2: (40 points)
Assume that a daytime server Q2S may serve only those clients that either has the same IP address A “ OR ” the same port number P as itself.
1.
Is it possible to replace the word “
OR
” with “
AND
”?
Solution
4
2.
Write the code for such server S. The server port P is specified as a command-line argument. E.g.,
% Q2S 1234
Solution ( S2S code C or Java)
5
3.
Write the code for a client Q2C that can always talk to that server S if it runs on the same host as S and do its best to talk to S if it runs on different host from S. The server’s IP address
A and port number P are specified as command-line arguments for C. E.g.,
% Q2C 128.82.4.7 1234
Solution ( Q2C Code C or Java)
6
4.
Is it possible to run the client as:
% Q2C 127.0.0.1 1234 &
% Q2C 127.0.0.1 1234
Solution
5.
Assume the client at host 128.82.4.8, is it possible to run two instances of the client as:
% Q2C 128.82.4.7 1234 &
% Q2C 128.82.4.7 1234
Solution
6.
Why Q2C cannot “always” talk to Q2S if it runs on a different host?
Solution
7
The following code (Q3v1.c) is for a daytime client. If the server has no room in its connection queue, then the client will timeout after a long time, typically a couple of minutes (many of you may have experienced this kind of delay in developing assignment 2).
To shorten this connection timeout period, the next version (Q3v2.c) uses select to achieve this goal. E.g.,
% Q3v2 127.0.0.1 1234 10 will limit the connection timeout to 10 seconds (the daytime server is assumed to run on the localhost at port 1234).
If the daytime server is a “lazy” server (e.g., takes a long nap between serving clients) then C might wait a long time to get the daytime.
Modify Q3v2.c to produce a new version, Q3v3.c, to limit the server response delay. E.g.,
% Q3v3 127.0.0.1 1234 10 5 will limit the server response delay to only 5 seconds.
8
}
Q3v1.c: int main(int argc, char **argv)
{
int sockfd, n;
struct sockaddr_in servaddr;
char recvline[MAXLINE + 1];
if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(atoi(argv[2]));
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
if ( (n = read(sockfd, recvline, MAXLINE)) <= 0)
err_sys("read error");
recvline[n] = 0; /* null terminate */
Fputs(recvline, stdout);
exit(0);
}
Q3v2.c: int main(int argc, char **argv)
{
int sockfd, n, flags, error;
struct sockaddr_in servaddr;
char recvline[MAXLINE + 1];
fd_set rset;
struct timeval tval;
if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(atoi(argv[2]));
flags = Fcntl(sockfd, F_GETFL, 0);
Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
error = 0;
if ( (n = connect(sockfd,(SA *) &servaddr, sizeof(servaddr))) < 0)
if (errno != EINPROGRESS){
Fputs("Connection Error\n", stdout);
exit(0);
}
if (n != 0) { /* connect not completed immediately */
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
tval.tv_sec = htons(atoi(argv[3]));
tval.tv_usec = 0;
if ( select(sockfd+1, &rset, NULL, NULL, &tval) == 0) {
Fputs("Connection Timeout\n", stdout);
exit(0);
}
}
Fcntl(sockfd, F_SETFL, flags);
if ( (n = read(sockfd, recvline, MAXLINE)) <= 0)
err_sys("read error");
recvline[n] = 0; /* null terminate */
Fputs(recvline, stdout);
exit(0);
9
Solution (Q3v3.c) int main(int argc, char **argv)
{
int sockfd, n, flags, error;
struct sockaddr_in servaddr;
char recvline[MAXLINE + 1];
fd_set rset;
struct timeval tval;
if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(atoi(argv[2]));
flags = Fcntl(sockfd, F_GETFL, 0);
Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
error = 0;
if ( (n = connect(sockfd,(SA *) &servaddr, sizeof(servaddr))) < 0)
if (errno != EINPROGRESS){
Fputs("Connection Error\n", stdout);
exit(0);
}
if (n != 0) { /* connect not completed immediately */
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
tval.tv_sec = htons(atoi(argv[3]));
tval.tv_usec = 0;
if ( select(sockfd+1, &rset, NULL, NULL, &tval) == 0) {
Fputs("Connection Timeout\n", stdout);
exit(0);
}
}
Fcntl(sockfd, F_SETFL, flags);
if ( (n = read(sockfd, recvline, MAXLINE)) <= 0)
err_sys("read error");
recvline[n] = 0; /* null terminate */
Fputs(recvline, stdout);
exit(0);
}
10