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 21.1. We begin the stream Daytime server with the Stream_Server procedure (lines 4-13). The procedure begins with the declaration and the requirement of a port argument (the port number on which the server should be bound on the current host). At line 8, a new socket is created as a server (-server) with the definition of a callback procedure ServerAccept to call for accepting new client connections. We also present the port number that was passed in by the caller. The new socket is stored into the s variable, but as can be noted, this variable will no longer be referenced. The final line in the Stream_Server procedure is the vwait command. This command invokes the Tcl event loop, which is used to await new events from the underlying system. The vwait command references a variable, which upon change will cause a return and a continuance. The forever variable is not declared (and will never be changed), so this procedure stalls at this line indefinitely.

Note 

The event loop (as invoked by the vwait call in Listing 21.1) is required in this application for proper operation (under Tcl). If this application had utilized the wish interpreter, the event loop would have been automatic, and, therefore, the vwait command would not have been necessary.

The ServerAccept procedure (lines 19-40) is the callback for the server socket that is called when an incoming connection arrives. The callback includes the new client socket (created as with the standard BSD accept function), the address of the client that was accepted (addr), and the port of the remote client socket (port). The first task is to emit some debugging data identifying the new client socket and from where the client is connecting (line 22). Next, the client socket is configured for buffering. This allows us to send data without having to perform a flush operation and so that data for read is available right away. We specify the socket for fconfigure and the type of configuration we're requesting-in this case line, buffering (line 26). In lines 29 and 32, we create our date and time string by first reading the current clock value in seconds (using the clock command with parameter seconds) and storing this in clock_val (line 29). Then, we convert this to a string using the clock command with the option format and the time value stored in clock_val (line 32). Finally, we emit the newly created date and time string (date_str) at line 35 using the puts command referencing the client socket and the date_str and then close the socket at line 38 using the close command.

The stream server is started at line 46 by invoking the newly created Stream_Server procedure, specifying the port number on which we want to bind (in this case, port 13).

Listing 21.1 Tcl Daytime stream server.

start example
  1   #  2   # Stream server setup  3   #  4   proc Stream_Server { port } {  5  6     # Create the server socket and set the accept  7     # event callback.  8     set s [socket -server ServerAccept $port]  9 10     # Wait for an event to occur 11     vwait forever 12 13   } 14 15 16   # 17   # Event callback for the socket accept 18   # 19   proc ServerAccept { sock addr port } { 20 21     # Emit some debugging information 22     puts "Accept $sock from $addr port $port" 23 24     # Configure the socket so that each puts results 25     # in a socket send. 26     fconfigure $sock -buffering line 27 28     # Get the current time in seconds 29     set clock_val [ clock seconds ] 30 31     # Convert the seconds time into string 32     set date_str [ clock format $clock_val ] 33 34     # Emit the date/time string to the socket 35     puts $sock $date_str 36 37     # Close the socket 38     close $sock 39 40   } 41 42 43   # 44   # Start the stream server on port 13 45   # 46   Stream_Server 13
end example

Stream Client

Now, let's look at the Daytime stream client (shown in Listing 21.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.

The client activity in Tcl is very simple, as is illustrated in Listing 21.2. First, the client socket is created at line 2 using the socket command, specifying the host to which we'll connect (in this case, localhost) and the port (13). The new client socket is then stored in variable sock. At line 5, we read a line from the socket using the gets command, specifying the client socket and storing the result in line. Finally, at line 8, we emit the line read from the socket to standard-out using the puts command.

Listing 21.2 Tcl Daytime stream client.

start example
 1   # Create the client socket and connect it to the server 2   set sock [socket localhost 13] 3 4   # Receive a line of text through the socket 5   gets $sock line 6 7   # Emit the line of text 8   puts $line
end example

Another potential solution to the Daytime stream client using the Tcl-DP package is shown in Listing 21.3. Although no simpler than the version using the standard Tcl libraries, it represents another way to handle streams.

Listing 21.3 Tcl Daytime stream client using Tcl-DP.

start example
 1   package require dp 4.0  2  3   # Connect via TCP to port 13 of the local host  4   set chan [dp_connect tcp -host localhost -port 13]  5  6   # Read a line from the channel  7   set line [dp_recv $chan]  8  9   # Emit the line 10   puts $line
end example

In Listing 21.3, line 1 begins by importing the package dp. The package command specifies that the following script requires the package (via the require keyword), the package to be imported (dp), and, finally, the version of the package that is desired (in this case, 4.0). Line 4 uses the dp_connect command to connect to the defined host and port using the stream protocol, TCP. The result is a new channel for the newly connected socket, which we store in chan. At line 7, we read a line from the socket using the dp_recv command, specifying the channel from which we'll read (chan) and the variable to which we'll store the result (line). Finally, we emit the line read from the socket to standard-out using the puts command.



 < 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