Todd Coram Hyping Tcl's powerful
Networking Capabilities... Below is a simple, line-oriented, event-driven, multiple-client server template.
proc register_client {line_cmd open_cmd close_cmd chan add port} {
# We want whole lines
#
fconfigure $chan -blocking 0 -buffering line
# Invoke a proc to notify us that a client has registered.
#
eval $open_cmd $chan
# Set up a fileevent to handle input
#
fileevent $chan readable [list handle_input $chan $line_cmd $close_cmd]
}
# Handle a complete line of input.
#
proc handle_input {chan cmd close_cmd} {
if {![eof $chan]} {
if {[gets $chan data] == -1} {
return; # only handle complete lines
}
} else {
# Close up the channel and notify us that a client was disconnected.
#
fileevent $chan readable {}
catch {close $chan}
eval $close_cmd $chan
return
}
# Handle the line of data
#
eval $cmd $chan \$data; # don't expand $data, pass as single arg
}
#
# Fill in these procs with your program logic
#
proc bgerror {msg} {
# Handle unexpected errors here.
# puts "Ack! $msg"
}
proc handle_line {chan line} {
# Handle a line of input
# puts "Got $line from $chan"
}
proc finished {chan} {
# Connection has been terminated.
# puts "Goodbye $chan!"
}
proc hello {chan} {
# Connection has been accepted.
# puts "Hello $chan!"
}
#
# Start a server on port 6668
#
socket -server [list register_client handle_line hello finished] 6668
vwait ::forever_and_ever_in_a_mainloop