First we present the program and a summary of the commands in it. After that we'll look at parts of the program in more detail.
(Make sure you've skimmed over the Tcl Syntax first.)
Echo ServiceDownload# Echo_Server -- # Open the server listening socket # and enter the Tcl event loop # # Arguments: # port The server's port number proc Echo_Server {port} { set s [socket -server EchoAccept $port] vwait forever } # Echo_Accept -- # Accept a connection from a new client. # This is called after a new socket connection # has been created by Tcl. # # Arguments: # sock The new socket connection to the client # addr The client's IP address # port The client's port number proc EchoAccept {sock addr port} { global echo # Record the client's information puts "Accept $sock from $addr port $port" set echo(addr,$sock) [list $addr $port] # Ensure that each "puts" by the server # results in a network transmission fconfigure $sock -buffering line # Set up a callback for when the client sends data fileevent $sock readable [list Echo $sock] } # Echo -- # This procedure is called when the server # can read data from the client # # Arguments: # sock The socket connection to the client proc Echo {sock} { global echo # Check end of file or abnormal connection drop, # then echo data back to the client. if {[eof $sock] || [catch {gets $sock line}]} { close $sock puts "Close $echo(addr,$sock)" unset echo(addr,$sock) } else { puts $sock $line } } # # A client of the echo service. # proc Echo_Client {host port} { set s [socket $host $port] fconfigure $s -buffering line return $s } # A sample client session looks like this # set s [Echo_Client localhost 2540] # puts $s "Hello!" # gets $s line |
Command Summary
|
set s [socket -server EchoAccept $port]In this case, EchoAccept is called each time a client connects to the server. For this to work, Tcl must enter the event loop so it can wait for the connection requests. The vwait command is used for this purpose. It puts Tcl into the event loop until the variable is modified. In this case, we never plan to modify the variable, so we call it "forever".
The event loop needs to be active for the callbacks to work. If you use wish for a Tk application, then the event loop is active automatically. However, if you use tclsh then you must activate the event loop explicitly. The vwait command enters the event loop until a variable is modified. You can use it for a short-term wait that is ended by setting the variable, or you can wait indefinetly.
The server puts the new socket into line-buffering mode so that each puts results in a network transmission. Otherwise Tcl buffers data until the buffer fills or a flush command is used. The fconfigure command sets up the buffering mode:
fconfigure $sock -buffering line
The EchoAccept procedure sets up another callback to handle the data from the client on the new connection:
fileevent $sock readable [list Echo $sock]The Echo command is called when the server can read the socket.
With fileevent the callback is a complete command that explicitly includes the new socket. The list command is used to create a well-formed Tcl command for the callback. (For more about list and eval, read about Quoting Issues and Eval)
The Echo command checks for end-of-file:
eof $sockThen it reads a line from the socket and catches error that might occur:
catch {gets file line}The first argument to catch is a script. Tcl will put the script through the normal evaluation cycle, so you can brace the whole script in curly braces. This example will run the gets command to read a line of input. That command could raise an error if the socket is in certain error states, so we put it inside a catch.
Finally, the server replies simply by writing the line back to the client:
puts $sock $line
set s [socket $host $port] fconfigure $s -buffering lineThe first command opens the TCP socket connection to the server (which triggers its call to EchoAccept). The second command sets up line buffering so each puts command results in a network transmission.
As an experiment, you can also try using the Unix telnet program to connect to your server. Most telnets take the port number as the second argument:
telnet hostname portAdd link to comments for /scripting/netserver.tml