2009年3月11日水曜日

Limboでネットワークプログラミング

なさけないことにARM上でinfernoは未だ挫折中です。
気分を変えてlimboでプログラミングをすることにしました。

ネットワークプログラミングの基本を学びました。
TCPソケット通信のやり方がなんとなく分かりましたので、公開します。

ネットで調べてもいまいちよく分からなかった所ですが、
httpdのソースを見ることでなんとなく分かりました。
付属のソースを取っ掛かりにするのはおすすめです。

以下ソースコードです。
これは、tcp通信のスループットを測るためのソフトを意図しています。
ttcpという既存のソフトウェアとの相互通信ができ、
ゆくゆくは完全互換のソフトになるのが目標です。
まだ作りかけですが、tcpでセッションを張り、データの受信はできています。

やってることは、
1. announce (ポートのopen?select?)
2. listen (着信待ち)
3. remoteのopen、read (相手のIPアドレス、ポートの取得、必須ではない)
4. dataのopen、read (データ受信)
です。

実行
- Inferno
このソフトを起動すると、待ち状態になるのでそのまま放置。

- 通信相手(Windowsとかunixとか)
ttcp またはwsttcp(Windows)を持ってきて
ttcp -t [InfernoのIPアドレス]
とする

こうすると通信相手からInfernoに対してtcpのセッションを張り、
データの通信が行われます。


# usage: ttcp [-t|-r]
# -t: send (not implemented)
# -r: receive

implement ttcp;

include "sys.m";
include "draw.m";

sys: Sys;

ttcp: module{
init: fn(ctx: ref Draw->Context, argv: list of string);
};

init(ctx: ref Draw->Context, argv: list of string)
{
buf :=array[64] of byte;

sys = load Sys Sys->PATH;

(ok, c):=sys->announce("tcp!*!5001");

if(ok < 0){
exit;
}

(ok2, nc):=sys->listen(c);

if(ok2 < 0){
exit;
}

l:=sys->open(nc.dir+"/remote", sys->OREAD);
n:=sys->read(l, buf, len buf);

sys->print("%s", string buf[0:n]);

b:=sys->open(nc.dir+"/data", sys->OREAD);
n=sys->read(b, buf, len buf);
sys->print("%s", string buf[0:n]);
}

※書きかけかつ詳細を理解していないので正直よろしくないコードです。
 各関数の意味を調べた上で書き直す予定ですのでご容赦を。


いい感じです。
直感的に書けるのでバグになりにくいかもしれませんね。
複数セッションをサポートする場合はスレッドを作りチャンネルでセッション情報を
渡せば良いのかもしれません。

ソースコード共有サイト(なのかな?)どう書く.org で細々とコードを書いているのですが、
最近あるブログにて私のエントリーを引用していただきました。
結構緊張しますが、励みにもなります。
どう書く.orgを勝手に自分用のコード置き場にしてしまっていましたが(テンプレート代わりに自分の投稿を使ってたりします。雛形を覚えられないのです。)、
少しは他の方の役に立てればうれしいです。

・今後の予定
ttcpを完成させ、スループットを評価する
グリッドコンピューティングを試してみる

1 件のコメント:

  1. 複数のセッションを受け入れるには、
    listenとspawnをfor(;;)に入れる。
    spawnされた子プロセスでは、/remote, /dataへのアクセスを行う。(Sys->Connectionを引数で渡す)

    返信削除