18.6 UICI ClientsProgram 18.3 shows the client side of the file copy. The client connects to the desired port on a specified host by calling u_connect. The u_connect function returns the communication file descriptor. The client reads the information from standard input and copies it to the server. The client exits when it receives end-of-file from standard input or if it encounters an error while writing to the server. Program 18.3 client.cA client that uses UICI for communication.
Exercise 18.13How would you use Programs 18.1 and Program 18.1 as server. First, start the server listening on a port (say 8652) by executing the following command.
Compile Program 18.3 as client. If the server is running on usp.cs.utsa.edu, start the client on another machine with the following command.
Once the client and server have established a connection, enter text on the standard input of the client and observe the server output. Enter the end-of-file character (usually Ctrl-D). The client terminates, and both client and server print the number of bytes transferred. Be sure to replace usp.cs.utsa.edu with the host name of your server. Exercise 18.14How would you use Programs 18.1 and Program 18.1 on the destination machine (say, usp.cs.utsa.edu) by executing the following command.
Start the client of Program 18.3 on the source machine by executing the following command.
Be sure to substitute your server's host name for usp.cs.utsa.edu. The source and destination files should have identical content. Since the messages are sent to standard error, which is not redirected, these messages still appear in the usual place on the two machines.The client and server programs presented so far support communication only from the client to the server. In many client-server applications, the client sends a request to the server and then waits for a response. Exercise 18.15How would you modify the server of Program 18.1 to produce a server called reflectserver that echoes its response back to the client, rather than to standard output?Answer:The only modification needed would be to replace the reference to STDOUT_FILENO with communfd.Program 18.4 is a client program that can be used with the server of Exercise 18.15. The reflectclient.c sends a fixed-length message to a server and expects that message to be echoed back. Program 18.4 checks to see that it receives exactly the same message that it sends. Program 18.4 reflectclient.cA client that sends a fixed-length test message to a server and checks that the reply is identical to the message sent.
Many client-server applications require symmetric bidirectional communication between client and server. The simplest way to incorporate bidirectionality is for the client and the server to each fork a child to handle the communication in the opposite direction. Example 18.16To make the client in Program 18.3 bidirectional, declare an integer variable, child, and replace the line
with the following code segment.
Exercise 18.17Suppose we try to make a bidirectional serial server from Program 18.1 by declaring an integer variable called child and replacing the following line with the replacement code of Example 18.16.
What happens?Answer:This approach has several flaws. Both the parent and child return to the u_accept loop after completing the transfer. While copying still works correctly, the number of processes grows each time a connection is made. After the first connection completes, two server processes accept client connections. If two server connections are active, characters entered at standard input of the server go to one of the two connections. The code also causes the process to exit if fork fails. Normally, the server should not exit on account of a possibly temporary problem. Example 18.18To produce a bidirectional serial server, replace the copyfile line in Program 18.1 with the following code.
The child process exits after printing its message. The original process waits for the child to complete before continuing and does not accept a new connection until both ends of the transmission complete. If the fork fails, only the parent communicates. Exercise 18.19The modified server suggested in Example 18.18 prints out the number of bytes transferred in each direction. How would you modify the code to print a single number giving the total number of bytes transferred in both directions?Answer:This modification would not be simple because the values for transfer in each direction are stored in different processes. You can establish communication by inserting code to create a pipe before forking the child. After it completes, the child could write to the pipe the total number of bytes transferred to the parent. Exercise 18.20Suppose that the child of Program 4.13 on page 111. The copy2files program copies bytes from fromfd1 to tofd1 and from fromfd2 to tofd2, respectively, without making any assumptions about the order in which the bytes become available in the two directions. You can use copy2files by replacing the copyfile line in both server and client with the following code.
Program 18.5 shows the bidirectional client. Exercise 18.21How does using copy2files differ from forking a child to handle communication in the opposite direction?Answer:The copy2files function of Program 4.13 terminates both directions of communication if either receives an end-of-file from standard input or if there is an error in the network communication. The child method allows communication to continue in the other direction after one side is closed. You can modify copy2files to keep a flag for each file descriptor indicating whether the descriptor has encountered an error or end-of-file. Only active descriptors would be included in each iteration of select. Program 18.5 client2.cA bidirectional client.
|