hae Nov 23 2009 - The Tcllib has the multiplexer package which can be used for this purpose, too.
set remote(host) "mush.pennmush.org" ;# host to connect to set remote(port) "4201" ;# port to connect to set remote(eol) "lf" ;# should be "lf" if newline_one_char is Yes, or crlf if it's No. ;# Or use "auto" if you prefer, but it may throw out an extra newline before every ;# line of output set local(port) "1642" ;# where we listen for connections - use "0" to have the program assign a port proc Server {channel clientaddr clientport} { global conn remote set x [incr conn(num)] Log "Connection from $clientaddr registered (number $x)" set conn($x,out) $channel set conn($x,host) $clientaddr set conn($x,port) $clientport if { [catch {socket -async $remote(host) $remote(port)} conn($x,in)] } { close $channel catch {array unset conn $x,*} return; } fconfigure $conn($x,out) -translation {auto lf} -blocking 0 -buffering line fconfigure $conn($x,in) -translation {auto auto} -blocking 0 -buffering line fileevent $conn($x,out) readable [list channelData $x out in] fileevent $conn($x,in) readable [list channelData $x in out] };# Server proc channelData {x 1st 2nd} { global conn if { [eof $conn($x,$1st)] || [catch {gets $conn($x,$1st)} data] } { catch {close $conn($x,in)} catch {close $conn($x,out)} if { $1st == "in" } { Log "Connection from $x's Client died." } else { Log "Connection from host on $x died." } return; } puts $conn($x,$2nd) $data };# channelData proc Start {} { global local conn array unset conn set conn(num) 0 set conn(connected) 0 if { [catch {socket -server Server $local(port)} conn(server)] } { Log "Unable to start Port-Forwarding: $conn(server)" unset -nocomplain conn(server) } set conn(conected) 1 Log "Port-Forwarding Server Connected" set good 0 foreach x [list www.google.com www.yahoo.com www.whois.sc www.pennmush.org www.talvo.com] { if { ![catch {socket $x 80} s] } { Log "Listening for connections on: [lindex [fconfigure $s -sockname] 0]:$local(port)" set good 1 close $s break; } } if { !$good } { Log "Unable to determine home IP. Sorry!" } };# Start proc Log {txt} { .t insert end "$txt\n" };# Log proc main {} { pack [text .t -yscrollcommand ".s set" -wrap word] -side left -expand 1 -fill both -side left pack [scrollbar .s -command ".t yview"] -side left -fill y bind . <F1> {console show} };# main main Start