211k views
4 votes
In this assignment, you are provided with almost-working code that establishes a TCP

socket connection over the INET domain (though for this assignment you should run
and test your client-server code on the same machine). What is missing are the actual
parameters for each of the four connection establishment socket APIs on the server and
the two connection establishment socket APIs on the client (you will see a ? where the
function parameters should be). Here are some identifying characteristics about the
sockets you will be creating:
• Use the INET domain for the socket type.
• Use TCP sockets.
• Use a backlog of 10 partially completed connections for the kernel to queue.
Your goal for the first part of this assignment is to fill in the socket APIs with their
needed parameters, but you should not add any new lines of code (until told to do so)
as all of the needed supporting information such as variable declarations and
initializations has already been provided. Use what is given to you, but do not change
the intent of the program.
If completed successfully, you will see the message "Server Message: SUCCESS" on
the client side, but nothing on the server-side (although the server-side should still be
running). The client-side only runs once while the server-side runs indefinitely, so you
can run the client multiple times.
To quit the server-side program, you may use CTRL-C (i.e., ^C). Go ahead and stop the
server-side socket program now and then attempt to run the server-side socket program
again. Does it work? Or does it give you an error? Knowing why you are getting this
error is important! Normally, we would call unlink() to delete the socket "file", but this
only works on UNIX domain sockets, not the INET sockets that we are using. For INET
sockets, there is no file system token representing them, so we need to set a socket
option to re-use the address as follows:
int on = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
Now, enter the above two lines of code just before where the error is occurring. Then
recompile and run your socket program again. Hopefully, you will no longer get these
same errors as before. Make sure your client-server socket program works as expected
and then submit both code files.

SERVER CODE

// compile: gcc rec09svr.c -o rec09svr
// usage : ./rec09svr port
#include
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0, cli_size, portno;
struct sockaddr_in serv_addr, cli_addr;
char sendBuff[1025];

if ((listenfd = socket( ? )) == -1)
{
printf("socket error\\");
exit(EXIT_FAILURE);
}
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
portno = atoi(argv[1]);
serv_addr.sin_port = htons(portno);
if (bind( ? ) == -1)
{
printf("bind error\\");
exit(EXIT_FAILURE);
}
if (listen( ? ) == -1)
{
printf("listen error\\");
exit(EXIT_FAILURE);
}
while (1)
{
cli_size = sizeof(cli_addr);
if ((connfd = accept( ? )) == -1)
{
printf("accept error\\");
exit(EXIT_FAILURE);
}
strcpy(sendBuff, "Server Message: SUCCESS\\");
write(connfd, sendBuff, strlen(sendBuff));

close(connfd);
sleep(1);
}

return 0;
}

CLIENT CODE

// compile: gcc rec09cli.c -o rec09cli
// usage : ./rec09cli port
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[])
{
int sockfd = 0, n = 0, portno;
char recvBuff[1025];
struct sockaddr_in serv_addr;

memset(recvBuff, '0', sizeof(recvBuff));
if ((sockfd = socket( ? )) < 0)
{
printf("socket error\\");
exit(EXIT_FAILURE);
}

serv_addr.sin_family = AF_INET;
portno = atoi(argv[1]);
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

if (connect( ? ) < 0)
{
printf("connect error\\");
exit(EXIT_FAILURE);
}

while ((n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if (fputs(recvBuff, stdout) == EOF)
{
printf("fputs error\\");
}
}

if (n < 0)
{
printf("read error\\");
}

return 0;

User NBajanca
by
8.2k points

1 Answer

7 votes

Final answer:

The assignment involves filling in the correct parameters for socket API functions in C to establish a TCP connection on the same machine.

Step-by-step explanation:

The student is tasked with completing the socket API parameters for a TCP socket connection program in the INET domain, using C programming language. For the server code, the correct parameters for the socket() system call would be AF_INET for the domain, SOCK_STREAM for the TCP socket type, and 0 for the protocol which typically defaults to TCP. The bind() function needs the listenfd as the socket file descriptor, a pointer to serv_addr as the address to bind to, and the size of serv_addr. For the listen() function, the parameters are the socket file descriptor listenfd and the backlog size, which is 10. The accept() function in the server code requires the listenfd, a pointer to the client address structure cli_addr, and a pointer to the size of this structure which is cli_size.

On the client side, the socket() call will have the same parameters as the server. However, for the connect() call, the parameters needed are the socket file descriptor sockfd, a pointer to serv_addr, and the size of serv_addr. The use of setsockopt() with the SO_REUSEADDR option is crucial for allowing the server to bind to a port that has been used recently.

Parameters for socket(), bind(), listen(), and accept() calls are required for the server-side, while the client needs parameters for socket() and connect(). The use of setsockopt() with SO_REUSEADDR option enables the server to reuse the port immediately after the program is restarted.

User Ivan Beldad
by
8.4k points