[Richard Suchenwirth] 2006-02-28 - The following very simple script can act as either the server or the client of a [socket] connection: * When called with "server" as first argument, it listens on the given port. Lines coming in are evaluated, and the result is sent back * Otherwise, the script is a client: takes lines from stdin, sends them to the server, displays the result ---- set host localhost set port 9900 if {[lindex $argv 0] eq "server"} { puts "Server started..." socket -server server $port } else { set chan [socket $host $port] fconfigure $chan -buffering line fileevent $chan readable [list client'read $chan] fileevent stdin readable [list client'send $chan] } #----------------------------------------------------- proc server {chan addr port} { fconfigure $chan -buffering line ;# NOT -blocking 0 (see below!) while {[gets $chan line]>=0} { catch $line res puts $line->$res ;# local logging puts $chan $res } close $chan } #------------------------------------------------------ proc client'read chan { if {[eof $chan]} {close $chan; exit} gets $chan line puts <-$line } proc client'send chan { gets stdin line puts $chan $line } #------------------------------------------------------ vwait forever ---- [RS] 2008-09-26 - Years (and possibly some "security" patches) later, this code runs no more on Win XP - the server starts up and waits, but clients get an EOF before they can even send something. Does anyone have an idea what could lead to this changed behavior? [MS] seems to recall that XP's firewall also blocks connections to localhost. [RS] 2008-10-02: no, it was something different.. someone edited ''-blocking 0'' into the server [fconfigure]. Taking that out again, it now works like it always did, at least on Windows XP :^) [Lars H]: That means it operates in a rather unusual fashion, though. The server can only serve one connection at a time, since it sits in the '''server''' while loop rather than the event loop. How about proc server {chan addr port} { fconfigure $chan -buffering line -blocking 0 fileevent $chan readable [list server_eval $chan] } proc server_eval {chan} { if {![eof $chan]} then { gets $chan line catch $line res puts $line->$res ;# local logging puts $chan $res } else { close $chan } } ? ---- ''See also:'' * [A Server Template] * [client/server with fileevent] * [Network server application template] * [Simple Server/Client Sockets] * [The simplest possible socket demonstration] * A Thread-based Network Server is demonstrated in [http://www.activestate.com/blog/2010/05/concurreny-tcl-weaving-threads%|%Concurreny in Tcl: Weaving Threads%|%] ---- !!!!!! %| [Category Example] | [Category Interprocess Communication] |% [Arts and crafts of Tcl-Tk programming] !!!!!!