Tcl/Tk 入門

Tcl/Tk によるサーバクライアント間通信

最終更新:[1999/09/30]
Copyright

Tcl/Tk のアプリケーション間での通信には send コマンドを使用することがで きますが,さらにネットワーク上の他ホストにあるアプリケーションとの通信が ソケットプログラミングによって可能になります.Tcl では,このソケットの利 用が簡単に行えます.

次に示す 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 のお手軽な強力さを表しているのかもしれません.

参考文献


server.tcl

#!/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

client.tcl

#!/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

||Tcl/Tk 入門||