VC++のCSocketの馬鹿ー!!
ソケット通信を扱うプログラムを組む必要に迫られて、そんなの大学の実習以来だし、時間的な余裕もないから、動作実績のあるコードを引っ張ってきて改造しようと考えました。
使っている開発環境はVisual C++ .net 2003なので、とりあえずサンプルコードのCHATSRVRに手を加えてみようと、ソケットがらみの部分だけ取り出して、CHATSRVRの通信内容に依存する部分を汎用的な感じに書き換えていきました。デバッガで起動して通信相手のアプリとの通信を試してみたところ、一応動作してるらしい……はずが、しばらく動かしてると、何故か通信が止まってしまいます。
通信しては内容をエディットコントロールに書き出すように作ったのですが、最初の1往復分のログしか書き出されません。
相手のソフトも自作で、そちらが固まってることも考えられるので、そちらもデバッガで起動して、交互に動作を確認したところ、相手の送信は実行されているのに、こちらの受信イベントが発生していない様子。
OnReceiveを取りこぼす可能性って……、と調べてみると、「MFC ソケットの使用時によくある 2 つの誤りを回避するサンプル プログラム MFCSocs.exe」という記事が見つかりました。それによると、
データの転送速度が速い環境で、OnReceive 関数内で Receive 呼び出しを複数回実行すると、アプリケーションで FD_READ が認識されなくなり、偽の FD_READ が生成されるか、FD_READ が失われる (ハングする) ことがあります。
とのこと。
でも、使っているのはアーカイブ付きのCSocketで、Receiveは私の見えていないところで呼ばれてると思うんですけど。とりあえず、OnReceive内であんまり処理しない方がいいのかな……。
ということで、OnReceiveからメッセージをポストして、一旦処理を抜けてからデータ取り込みをするようにしてみました。何だかさっきよりはサクサク動いてる気がしま……やっぱり数回で止まりました。
更に情報を集めていると、同じ問題に当たった記事が見つかりました。そこで紹介されていたマイクロソフトのサポートページの記事によると、「MFC CSocketFile とマルチプロセッサ環境での CArchive クラスのシリアル化を実行すると、アプリケーションは、停止することがあります。」
コレか。
私のPCのCPUはHTなPen4ということで、実質2CPUなのですよ……って、最近はデュアルコアとかクアッドコアとか普通じゃないのん?実質アーカイブ付きソケットは使えんということ!?
しょうがないので、CAsyncSocketでがっつり書き直しました。今度はちゃんと動いているように見えます。ってか、反応が全然違います。
…………。
ヽ(`Д´)ノ ≡≡≡≡ [VC++]
| 固定リンク
この記事へのコメントは終了しました。
コメント