Stream (TCP) ServerClient

 < Day Day Up > 



Stream (TCP) Server/Client

The stream server and client demonstrate the Daytime protocol using stream sockets (reliable TCP-based communication).

Stream Server

The Daytime protocol stream server is shown in Listing 20.1. Because all networking applications must have access to the socket classes, we first make the socket classes visible by including the socket library using require (line 1). At line 2, we create our server socket using the TCPServer class. We bind our new server to all interfaces (as we’ve left the interface spec out) and the daytime port (which will resolve to 13). We could achieve the same result by specifying the host as “0.0.0.0”, which is synonymous with INADDR_ANY (from the C language perspective).

With our server socket defined in servsock, we emit some data for debugging purposes (to show the address of the server). The address printed will be “0.0.0.0”, as discussed previously. Next, we enter the infinite loop awaiting connections from external client sockets.

To accept a client connection, we use the accept instance method. This method returns a socket instance representing our connection to the client (line 13). We again emit some debugging information to show that a client successfully connected, and some information about it (lines 16 and 17).

In lines 20 and 21, we emit the time through the client socket. Note the use of Time::new, which returns a string representing the current time. We anonymously create the time string (returned by Time::new) and send it to the client using the write method. Because the time string contains no newline, we follow with another write (line 21) to ensure that the client receives a newline for proper printing. Because we’re now finished communicating with the client socket, we close it at line 24. This stops all communication with the client, except that any data remaining to be sent will be sent before the socket is physically closed.

Finally, at line 26, we terminate our while loop so processing begins again at line 13, awaiting a new client connection.

Listing 20.1 Ruby Daytime stream server.

start example
  1   require ‘socket’  2  3   # Create a new TCP Server using port 13  4   servsock = TCPserver::new("daytime")  5  6   # Debug data -- emit the server socket info  7   print("server address : ",  8          servsock.addr::join(":"), "\n")  9 10   while true 11 12     # Await a connection from a client socket 13     clisock = servsock.accept 14 15     # Emit some debugging data on the peer 16     print("accepted ", clisock.peeraddr::join(":"), "\n") 17     print(clisock, " is accepted\n") 18 19     # Emit the time through the socket to the client 20     clisock.write( Time::new ) 21     clisock.write( "\n" ) 22 23     # Close the client connection 24     clisock.close 25 26   end
end example

Before we move on to discuss the stream client, let’s discuss the method used to emit the debugging data at lines 8 and 16. The instance methods addr and peeraddr return information about the local socket and peer socket, respectively, in array form. The purposes of the join method are to create a new string by joining the elements together of the initial string and to separate them by the string argument to join (in this case, a ‘:’). This permits us to view the contents of the given array. For example, line 8 generates:

server address : AF_INET:13:0.0.0.0:0.0.0.0

The contents of the new array are “AF_INET” (the address family), 13 (the port), the resolved address (“0.0.0.0”, which is actually unresolved), and, finally, the IP address attached to the interface (“0.0.0.0”). Recall that because we specified no host in the creation of the TCP server socket, it was bound to the wildcard address so that connections could be accepted on any available interface (including localhost).

Stream Client

Now, let’s look at the Daytime stream client (shown in Listing 20.2). The client creates a socket to connect to the server and then awaits a string to be received through the socket. Upon receiving the string from the server, the message is printed and the client exits.

Listing 20.2 Ruby Daytime stream client.

start example
 1   require ‘socket’  2  3   # Create a new client socket to the daytime port  4   mysock = TCPSocket::open("localhost", "daytime")  5  6   # Read a line from the socket  7   line = mysock.gets  8  9   # Print the line 10   print line 11 12   # Close the socket 13   mysock.close 
end example

We begin by making the socket library visible using the require method in line 1. Next, we create our stream using the TCPSocket class and the open method (line 4). We specify “localhost” as the host to connect, which is the loopback interface on the current host. We also specify the “daytime” port, which Ruby will resolve to 13. Recall that the TCPSocket::open method not only creates the client socket, but also connects it to the server as defined by the arguments. Therefore, when this method completes, we’ll be ready to communicate with the server.

To receive the time string from the server, we use the gets method with our previously created TCPsocket instance (mysock). The result of the gets method is a single line of input from the socket, which is stored in the line variable (line 7). We emit this string at line 10 using the print method and finally close the socket at line 13 using the close method.

Before we leave stream clients, let’s look at a simplified version of the Ruby stream client (shown in Listing 20.3). This client performs the socket creation followed by a gets method to retrieve the time string from the server. The entire line is preceded by the print method that emits the response from the socket methods.

Listing 20.3 Simplified Ruby Daytime stream client.

start example
 1   require ‘socket’ 2 3   # Short version -- open, read, close, and print in one line 4   print TCPSocket::open("localhost", "daytime")::gets 
end example

Scripts built with this style of method invocation are limited, but as is illustrated by Listing 20.3, can still be very useful.



 < Day Day Up > 



BSD Sockets Programming from a Multi-Language Perspective
Network Programming for Microsoft Windows , Second Edition (Microsoft Programming Series)
ISBN: 1584502681
EAN: 2147483647
Year: 2003
Pages: 225
Authors: Jim Ohlund

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net