Last updated: "2005/03/30 18:11:41 +0900"
小松平良樹プレゼンツ
ごくごく適当な tftp サーバ (tttftpd.exe)、tftp クライアント (tttftpc.exe) を 作ってみました。適当過ぎてひどいもんですすんません。 でも cassiopeia A-11 で動きます。って言い訳になんないけど。
伊藤栄一郎さんの "CONSOLE" 上で 動作します。 CONSOLE が動作する機械の上では、たいてい動くのでは ないかな。SH3, MIPS, WIN32 のバイナリを用意しました。WIN32 版は MS-DOS プロンプト上で動作します。
SH3 のバイナリはリンカオプションに "/align:4096" をつけました。 persona HPW-600JC (WindowsCE2.11, SH4) でも動作することをなんとなく 確認しています。 SH4 用の CONSOLE は公開されていないのですが、伊藤栄一郎さんが 公開してくださっているソースを、"/align:4096" をつけてビルドすると、 HPW-600JC で動作します。
WIN32 版は、borland C 5.5.1 でビルドしました。
(20050327 版の話)
WIN32 版は、Digital Mars Compiler 8.38 でビルドしました。 この時点での最新版 8.42 は、"-j0" をつけるとなんかちゃんと動かない...。
WindowsCE1.0 での開発に関しては、 WindowsCE1.0 development with EVT3.0 にちらと書きました。こちらも参照のこと。
omiokone さんが 非常に有益な情報をご提供くださっています。というか、私の上述の 情報は、omiokone さんの情報がベースです。
iruka さんの "libce" を利用させていただきました。ありがとうございます。
tttftpd.exe は、起動時のカレントディレクトリをカレントディレクトリとします(?)。 パーミッションはなんにも考えていません。tttftpc.exe で パスを付けて tttftpd.exe に読み書きを行うと、ファイルシステムが丸見え、 しかもどこにでも書き込みできるんじゃないかなあ。試してないけど。 非常に危険です。使用は自己責任で。何が起こっても責任はとりませんので よろしくどうぞ。
しかも tttftpd.exe には、終了の UI がありません。コンソールに何か 出力するタイミングで CTRL+C するか、CONSOLE を強制終了するかしないと 止まりません。
debug build は、なんか debug print が出ます。普通は release build を 使えばいいと思いますが、tftp を使うということは転送速度はそんなに 重視しないのでしょうから、debug build で動作状況を見るのもいいかも しれません。
アーカイブファイルはこちら。
手元で軽く動作確認した環境は次の表の通り。動作確認はほんとに軽くしか していないので、ちゃんと動かない可能性が大有りです。お許しを。
| 機械 | ネットワーク | 動作 |
| Windows98SE PC | イーサネット | ○ |
| cassiopeia A-11 (WindowsCE1.0, SH3) | IrDA | ○ |
| cassiopeia E-65 (WindowsCE2.11, MIPS) | IrDA | ○ |
| persona HPW-600JC (WindowsCE2.11, SH4) | IrDA | ○ |
| cassiopeia l'agenda BE-500 (WindowsCE3.0, MIPS) | イーサネット | ○ |
| Sigmarion2 (WindowsCE3.0, MIPS) | イーサネット | ○ |
| Sigmarion2 | IrDA | ○ |
IrDA というのは、Windows98SE の PC と、IrDA で「ケーブル接続」により 接続した状態です。
なんかしらんけど、A-11 上では、recvfrom() がブロックしません。 受信データグラムがないときには、SOCKET_ERROR を返し、 そのときの WSAGetLastError() は WSAEWOULDBLOCK です。
いや nonblocking mode にしていればそりゃその通りなのですが,,, socket 生成して何もしなくても (default 状態で) ブロックしないの。 ioctlsocket() で明示的に blocking mode にしてもブロックしないのだ。
cassiopeia A-60 (WindowsCE2.0, SH3) や cassiopeia E-65 (WindowsCE2.11, MIPS) では、 普通にブロックします。
WindowsCE1.0 では nonblocking mode しか使えないのかな。
しょうがないので、明示的に nonblocking mode として、CE1.0 以外の 環境でも同じ動きをするようにして作ってみました。
次は 20050327 時点の話。
RRQ, WRQ の処理を開始した後、 受信データグラムがないときには Sleep(10) とかしてぐるんぐるん回っているので、 CPU を浪費します。なんかいい手ないですかね?
RRQ, WRQ を受ける前にも Sleep(10) だとあまりにもアレなので、そのときは Sleep(1000) とかしています。
上記は私の理解不足でした。
A-11 において recvfrom() がブロックしないようだ、というのは相変わらず なのですが、select() はちゃんと待ってくれるということがわかりました。 というか、見落としていました。
20050330 版では、select() して待ってから必要に応じて recvfrom() しているので、 馬鹿な力は使わないようになりました。
また、そうしないと、とってもスループットが落ちます。A-11 だともともとが 遅いからアレなのですが、win32 版だと全然変わってきちゃいますね。
どうもありがとうございます。
すげー環境である CONSOLE を 公開 してくださっている伊藤栄一郎さん。
開発環境に関して非常に有益な情報を 公開 してくださっている omiokone さん。
すげー便利な標準入出力環境を 公開 してくださっている iruka さん。