The Echo Service

   

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 17.  Socket Programming


Example 17-3 The echo service.
 proc Echo_Server {port} {    global echo    set echo(main) [socket -server EchoAccept $port] } proc EchoAccept {sock addr port} {    global echo    puts "Accept $sock from $addr port $port"    set echo(addr,$sock) [list $addr $port]    fconfigure $sock -buffering line    fileevent $sock readable [list Echo $sock] } proc Echo {sock} {    global echo    if {[eof $sock] || [catch {gets $sock line}]} {       # end of file or abnormal connection drop       close $sock       puts "Close $echo(addr,$sock)"       unset echo(addr,$sock)    } else {       if {[string compare $line "quit"] == 0} {          # Prevent new connections.          # Existing connections stay open.          close $echo(main)       }       puts $sock $line    } } 

The echo server accepts connections from clients. It reads data from the clients and writes that data back. The example uses fileevent to wait for data from the client, and it uses fconfigure to adjust the buffering behavior of the network socket. You can use Example 17-3 as a template for more interesting services.

The Echo_Server procedure opens the socket and saves the result in echo(main). When this socket is closed later, the server stops accepting new connections but existing connections won't be affected. If you want to experiment with this server, start it and wait for connections like this:

 Echo_Server 2540 vwait forever 

The EchoAccept procedure uses the fconfigure command to set up line buffering. This means that each puts by the server results in a network transmission to the client. The importance of this will be described in more detail later. A complete description of the fconfigure command is given in Chapter 16. The EchoAccept procedure uses the fileevent command to register a procedure that handles I/O on the socket. In this example, the Echo procedure will be called whenever the socket is readable. Note that it is not necessary to put the socket into nonblocking mode when using the fileevent callback. The effects of nonblocking mode are discussed on page 221.

EchoAccept saves information about each client in the echo array. This is used only to print out a message when a client closes its connection. In a more sophisticated server, however, you may need to keep more interesting state about each client. The name of the socket provides a convenient handle on the client. In this case, it is used as part of the array index.

The Echo procedure first checks to see whether the socket has been closed by the client or there is an error when reading the socket. The if expression only performs the gets if the eof does not return true:

 if {[eof $sock] || [catch {gets $sock line}]} { 

Closing the socket automatically clears the fileevent registration. If you forget to close the socket upon the end of file condition, the Tcl event loop will invoke your callback repeatedly. It is important to close it when you detect end of file.

Example 17-4 A client of the echo service.
 proc Echo_Client {host port} {    set s [socket $host $port]    fconfigure $s -buffering line    return $s } set s [Echo_Client localhost 2540] puts $s "Hello!" gets $s => Hello! 

In the normal case, the server simply reads a line with gets and then writes it back to the client with puts. If the line is "quit," then the server closes its main socket. This prevents any more connections by new clients, but it doesn't affect any clients that are already connected.

Example 17-4 shows a sample client of the Echo service. The main point is to ensure that the socket is line buffered so that each puts by the client results in a network transmission. (Or, more precisely, each newline character results in a network transmission.) If you forget to set line buffering with fconfigure, the client's gets command will probably hang because the server will not get any data; it will be stuck in buffers on the client.


       
    Top
     



    Practical Programming in Tcl and Tk
    Practical Programming in Tcl and Tk (4th Edition)
    ISBN: 0130385603
    EAN: 2147483647
    Year: 1999
    Pages: 478

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