One reason Tcl is my favorite language is the ease with which you can write network applications.
Consider this little NNTP proxy. I want to be able to run a local news server (so I can read news offline) and a non-GUI newsreader on my PowerBook (to access comp.lang.tcl & other groups), but my current broadbrand provider has lousy news servers as compared to my longtime ISP (from whom, unfortunately, I cannot currently get DSL thanks to qworst).
I do have a friend, however, who lives only a mile away, who can get DSL. He's tenatively agreed to host this little proxy for me. That way I can connect to a good NNTP server without having my old credentials passing clear text over the Internet.
#!/usr/bin/tclsh proc accept {sock host port} { if {[lsearch -exact {127.0.0.1} $host] == -1 || [catch {socket -async news.example.com 119} conn]} then { catch {close $sock} } else { fconfigure $sock -blocking 0 -buffering line fconfigure $conn -blocking 0 -buffering line fileevent $sock readable [list copy-from-to $sock $conn] fileevent $conn readable [list copy-from-to $conn $sock] } } proc copy-from-to {source destination} { if {[eof $source] || [eof $destination] || [catch {puts $destination [gets $source]}]} then { catch {close $source} catch {close $destination} } } socket -server accept 8119 vwait forever
Actually, that should work with any line oriented protocol, not just NNTP.
The bolded items above are things you'd want to customize to your environment. You'd probably want to flush out the list of IP addresses you want to allow to connect to something beyond just 127.0.0.1 (or remove the check all together if you wanted to proxy for the whole world). You'd change where you are proxying to from news.example.com port 119 and (maybe) change the port that the daemon binds to from 8119 to something else.
—Michael A. Cleverly
Tuesday, June 07, 2005 at 21:39
Roberto Mello spotted a bug in the code (which I've taken the liberty of fixing; this comment is to give credit where credit is due...)
<blush>When I retyped the code and html-ized it I accidentally left out the $host from the [lsearch] command.</blush>