メモ帖 Winsock 同期 中断

メニュー









※このページは作成者の個人的メモです。
※このページは本文中に登場する各種団体の公式なページでは有りません。ゆえに各種団体へ本ページ群の内容に対してクレーム頂いても対応頂けません。
※その他注意書きが表紙にあります。

※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

Winsockを同期で使うときに、外部要因から中断したい。
どのようにすればよいか。

中断できない?
Winsock 2.0 プログラミング (ISBN4-7973-0688-2)のサンプルプログラムを試してみた。

(1)11章マルチスレッドサーバ にてポート25(SMTP)を待受けさせ、“メールを送りつけ”ようとしたところ、(HTTPサーバなので)電文が違うから当然とまる。で、このプログラムの「中止」ボタンを押したところ、10秒経って終了になる。サブスレッド終了待ちのWaitForSingleObject()がタイムアウト。ListenThread and/or ClientThreadが終了できていないようだ。
(2)10章非同期サーバ にて(同様に)ポート25(SMTP)を待受けさせ、…当然止まる。で、このプログラムの「中止」ボタンを押したところ即座に「Server Stopped」になる。

この2つを見比べて思う。
  • 同期ソケットは外部から停止できないのか。
  • 非同期ソケットは停止できるのか(停まっているが不具合隠れていないか)


これに対する解・hintを探してみる。
Winsock Programmer's FAQ: Articles: Which I/O Strategy Should I Use? ( http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/io-strategies.html )から:

どの I/O 戦略を使うべきか?

経験則1: どのOSのサポートが必要かを決定し選択肢を限定する。
経験則2: 単純な非ブロック型ソケットは避けること。
経験則3: select()は避ける。
 select()を使うべきなのは、互換性の理由があるときくらいでしょう。
 Unix と Windows CE 上で、同期型でないI/O戦略を効率良く行うには、
 非ブロック型ソケットに対して select() を使う方法しかありません。
 その他の場合には全て、より良い代替手法が存在します。
経験則4: 非常に大量のデータを扱うプログラムでは、非同期型ソケットは使わない。
経験則5: 高性能サーバでは、オーバーラップI/Oが望ましい。
経験則6: 中規模の数のコネクションをサポートするためには、非同期ソケットとイベントオブジェクトを検討する。
経験則7: トラフィックの少ないサーバでは、ほとんどどのI/O戦略でも使える
経験則8: ユーザインターフェースのスレッド内ではブロックしないこと
経験則9: GUIクライアントプログラムには、非同期ソケットが望ましい
経験則10: クライアントプログラムではスレッドはめったに役に立たない
経験則11: スレッドは、プログラムの他の部分への影響が全て丸く収まる場合にのみ使うべし
経験則12: プロトコル周りの設計
経験則 13: ブロック型ソケットの方が簡単、非ブロック型ソケットの方が強力
 この経験則は、ここまで上記で述べてきた内容の全てを言い換えたようなものです。
 繰り返しになりますが、ブロック型ソケットは簡単であるという点が魅力ですが、
 その欠点を考えたときに、結局は何らかの非ブロック型ソケットを使うように
 再設計せざるを得ない、ということがあり得ます。特に、一個より多くのソケットを
 サポートするプログラムではそれがあてはまります
 (実質的に全てのサーバプログラムはこのカテゴリに分類されます)。
 ブロック型ソケットを同時に複数使うために妥当な方法はただひとつ、
 スレッドを使用することだけですが、しかし非ブロック型ソケットを用いたほうが、
 より幅広い設計上の選択肢があります。

3:ふむふむ。
6:おっ、これはぴったしかんかん!
7:うっ。でも多分少なくない。
10:うぐっ。
11:うーむ…本文見ると、FTPサーバ・webブラウザ・メーラー・株価表示、なんてリストしてるが、自分のやろうとしてるものはどれにも(同じでないのはもちろんのこと)似てもいないなぁ。
12:相手がたとえばPOPサーバのごとく、シーケンシャルに処理があるので、状態遷移を書くのは避けられない…。。
13:うぅぅぅ…クリティカルヒット。悩み積もる。どーすりゃいいの。


もう少し見て回ろう。
同じFAQの Winsock初心者のための情報 ( http://www.kt.rim.or.jp/~ksk/wskfaq-ja/newbie.html#langcompat )から…

2.14 - Winsock 関数のタイムアウトを変更するにはどうするのですか?
これの解決方法は、ブロック型ソケットの利用を完全に止めることです。
非ブロック型ソケットの関数は全て、タイムアウトを行うことができるようにできています

うぅぅ。。。