Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

IN C Modify the code to allow half-duplex (simple two-way) communication by having the following interaction between the two programs: vcsend asks the user for

IN C

Modify the code to allow half-duplex (simple two-way) communication by having the following interaction between the two programs: vcsend asks the user for a string and sends it to vcrec vcrec echos the received string on screen vcrec asks the user for a string and sends it to vcsend vcsend echos the received string on screen Repeat steps 1-4 until the user enters a period by itself in either vcsend (step 1) or vcrec (step When the user enters a period, close the connection, and exit both vcrec and vcsend

vcsend code:

#include #include #include #include #include #include #include /* for gethostname() */ #include /* for IP address structures and functions */ #include /* for gethostbyname() */ int main(int argc, char *argv[], char *envp[]) { int msgsock; /* The data socket for the client */ struct sockaddr_in name; struct hostent *hp; /* Used to resolve hostname to IP address */ char chrline[80]; int i, ret, length;

/* We must give the hostname and portnumber on the command line. This * checks that the user has typed both. */ if (argc < 3) { printf("error: Invoke this program via: "); printf(" vcsend "); return (-1); } /* Since we are allowing a domain name as the hostname, we must call * gethostbyname() to convert the hostname into an IP address. */ hp = gethostbyname(argv[1]); if (hp == NULL) { printf("sender: gethostbyname() failed. "); printf(" Are you sure the hostname is correct? "); return (-1); } printf(" sender: hostname has been resolved. "); /* Copy the resolved IP address over into the name structure along with * the portnumber given on the command line */ memcpy((char *)&name.sin_addr, (char *)hp->h_addr, hp->h_length); name.sin_family = AF_INET; name.sin_port = htons((short)atoi(argv[2])); /* Allocate the data socket and attempt to connect to vcrec. Exit the * program if either socket() or connect() fails. */ printf("sender: Attempting to connect to server. "); msgsock = socket(AF_INET, SOCK_STREAM, 0); if (msgsock < 0) { perror("sender: socket() failed. "); return (-1); } ret = connect(msgsock, (struct sockaddr *)&name, sizeof name); if (ret != 0) { perror("sender: connect() failed. "); fprintf(stderr, " are you sure that the portnumber is correct? "); fflush(stderr); return (-1); } /* Wait for the handshake from vcrec before continuing */ printf("sender: Waiting for handshake from vcrec... "); sleep(1); /* pause for clean screen display */ fflush(stdout); recv(msgsock, chrline, sizeof(chrline) - 1, 0); /* Handshake character */ printf("sender: Handshake received. Entering data loop. "); printf(" Enter a line of characters at the prompt. "); printf("To exit the program, type just a period and hit enter. "); /* Go into an infinite loop. We'll use the "break" statement to exit * the loop if the user types a period or send() fails */ while(1)

{ printf("enter line> "); /* Read input from user */ fgets(chrline, sizeof(chrline) - 1, stdin); /* Check for the period to end the connection and also convert any * newlines into null characters */ for (i = 0 ; i < (sizeof(chrline) - 1) ; i++) { if ( (chrline[i] == ' ') || (chrline[i] == '\0') ) break; } if (chrline[i] == ' ') chrline[i] = '\0'; /* get rid of newline */ length = strlen(chrline); if (chrline[0] == '.') /* end of stream */ { printf("sender: termination requested "); break; /* Exit out of loop */ } ret = send(msgsock, chrline, length + 1, 0); if (ret < 0) { perror("sender: write() failed. "); break; /* Exit out of loop */ } } /* Closing the data socket from vcsend will trigger recv() on vcrec to * return 0, which will also cause vcrec to close its sockets and exit */ close(msgsock); return (0); } /* end of main */

vcrec code:

#include #include #include #include #include #include #include /* for gethostname() */ #include /* for IP address structures and functions */ int main(int argc, char *argv[], char *envp[]) { int sock, msgsock; /* Sockets are integer file descriptors on Linux */ struct sockaddr_in name, caller;

int size, length, ret, k; /* Process the command line for the buffer size, if given */ if (argc > 1) { size = atoi(argv[1]); /* Validate that the given argument is between 1 and sizeof(buf) - 1 * Set to the default size if argument is invalid */ if (size < 1 || size > sizeof(buf) - 1) size = sizeof(buf) - 1; } else { size = sizeof(buf) - 1; /* Default size */ } /* Create the listen socket. This is a TCP socket, so use SOCK_STREAM * Exit if the socket cannot be created */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("receiver: socket() failed. "); return (-1); } /* Bind the socket to an IP address and port. We will use the IP address * INADDR_ANY, which tells the system to assign the IP address, and the * port number 0, which tells the system to assign a random port number. * * First we have to set the fields in the sockaddr_in object "name" and then * we can call bind(). Again, exit if bind() fails. */ name.sin_family = AF_INET; /* TCP/IP family */ name.sin_addr.s_addr = INADDR_ANY; /* INADDR_ANY = assigned by system */ name.sin_port = htons(0); /* 0 = assigned by system */ ret = bind(sock,(struct sockaddr *)&name,sizeof name); if (ret < 0) { perror("receiver: bind() failed. "); return (-1); } /* In order to use vcsend to send data to this program, we need to know * what port number the system just assigned this program. So this segment * calls getsockname() to update the sockaddr_in object "name" with the * system assigned values and then print that info to the screen. */ length = sizeof name; ret = getsockname(sock, (struct sockaddr *)&name, (socklen_t *)&length); if (ret < 0) { perror("receiver: getsockname() failed. "); return (-1); } sleep(1); /* pause for clean screen display */ printf(" receiver: process id: %d ", (int)getpid()); printf(" receiver: IP address: %d.%d.%d.%d", (ntohl(name.sin_addr.s_addr) & 0xff000000) >> 24,

(ntohl(name.sin_addr.s_addr) & 0x00ff0000) >> 16, (ntohl(name.sin_addr.s_addr) & 0x0000ff00) >> 8, (ntohl(name.sin_addr.s_addr) & 0x000000ff)); printf(" receiver: port number: %hu", ntohs(name.sin_port)); printf(" "); fflush(stdout); /* Now we will call listen() and wait for a client to connect. The * accept() function will block until there is a client or an error. */ listen(sock,5); /* up to 5 clients can connect. only 1st is accepted */ k = sizeof caller; msgsock = accept(sock, (struct sockaddr *)&caller, (socklen_t *)&k); /* We only reach this point when there is an error or a client. We can * check the value of msgsock (the data socket) to see which has happened */ if (msgsock == -1) { perror("receiver: accept() failed. "); } else { printf(" receiver: Valid connection received. "); printf("receiver: Sending handshake. "); fflush(stdout); /* let vcsend know we are ready by sending a single character */ buf[0]= '0'; send(msgsock, buf, 1, 0); printf("receiver: Waiting for client.... "); do { bzero(buf,sizeof buf); /* zero buffer to remove old data */ /* recv() will block until the client sends information, the client * closes the connection or an error occurs on the data socket. */ ret = recv(msgsock, buf, size, 0); if (ret < 0) { perror("receiver: recv() failed. "); } if (ret == 0) { printf(" received-->sender has ended connection "); } else { printf(" received-->%s ",buf); } } while (ret != 0); /* Exit loop only when client ends connection */ } /* When we exit the recv() loop, the client has ended the connection, so * all that remains is closing the sockets. */ printf("receiver: ending session also and exiting. ");

close(msgsock); /* close data socket */ close(sock); /* close listen socket */ return (0); } /* end of main */

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Professional SQL Server 2012 Internals And Troubleshooting

Authors: Christian Bolton, Justin Langford

1st Edition

1118177657, 9781118177655

More Books

Students also viewed these Databases questions

Question

a sin(2x) x Let f(x)=2x+1 In(be)

Answered: 1 week ago

Question

How might HR technology affect the various HR functions?

Answered: 1 week ago