Tcl/Tk によるサーバクライアント間通信次に示す server.tcl と client.tcl は,それぞれが名前の通りサーバとそのク ライアントで,先に server.tcl を起動しておき client.tcl がそれにアクセス するという形になります.
server.tcl 中の socket -server でサーバとしての動作を開始します.引数は, ソケット接続されたときに呼び出されるプロシージャとポート番号です.ここで の例では暫定的に 8823 を使いました.呼び出しプロシージャとして指定したの は serverAdd です.呼び出し時には引数が3つ付加されます.それぞれ,接続 ソケット ID,ホストアドレス,ポート番号となります.
起動後は vwait で無限ループを構成して他のクライアントからの接続を待ちま す.
server_add 中では,ソケットが読みだし可能になったときに呼び出されるプロ シージャの登録とバッファリングの設定,という2つのことを行っています.登 録されるプロシージャは serverHandle としました.また,バッファリングは 行単位で行われるようにしています.一般的にサーバとの通信は行単位となって いるので,この点で整合性があります.
server_handle は登録したとおり,ソケットが読み出し可能となると呼ばれます. 内部の処理としては,ソケットから行を読み出す,EOF なら終了,何かコマンド があればそれに応じた処理をする,となります.ここでは単にクライアントから 送られて来た文字列をそのまま送り返す処理としています.
client.tcl で server.tcl のサーバへアクセスします.まず,socket によりソ ケットを指定したホスト,ポート番号で開きます.そして,サーバ側と同様にソ ケットが読み出し可能になったときに呼ばれるプロシージャを登録し,そのバッ ファリングを行単位に指定します.プロシージャは clientHandle として登録し ています.
clientHandle 中でも,行を読み込み,EOF なら終了,応答があればそれに従っ て処理をする,という形をとります.
send コマンドは Tcl/Tk アプリケーションでなければ使用できませんが,ソケッ トによれば,サーバ/クライアントが容易に構築でき,また,その各々は言語を 選びません.そして,ネットワーク上の別のホストとの通信が可能である利点が あります.
ソケットの扱いがこれほど簡単にできるとは思いませんでしたが,これも Tcl/Tk のお手軽な強力さを表しているのかもしれません.
#!/usr/local/bin/tclsh
proc serverAdd {sock addr port} {
    fileevent $sock readable "serverHandle $sock"
    fconfigure $sock -buffering line
}
proc serverHandle {sock} {
    set line [gets $sock]
    if {[eof $sock]} {
        close $sock
    } else {
	puts $sock "test from server: $line"
    }
}
socket -server serverAdd 8823
vwait forever
#!/usr/local/bin/tclsh
proc clientHandle {sock} {
    if {[gets $sock str] < 0} {
        catch {close $sock}
	exit
    } else {
	puts $str
    }
}
if {[catch {socket localhost 8823} sock] != 0} {
    puts "Cannot open socket 8823"
    exit
}
fileevent $sock readable "clientHandle $sock"
fconfigure $sock -buffering line
foreach str $argv {
  puts $sock $str
}
vwait forever