2025
01
30
2008
09
26
MFC ソケットの使用時によくある 2 つの誤り
1. | support.microsoft.com/kb/185728/ja OnReceive 通知関数で、Receive 呼び出しを複数回実行する。 CSocket クラスは、すべてのデータが受信されるか完全に送信されるまで CAsyncSocket Receive 呼び出しおよび CAsyncSocket Send 呼び出しをループすることにより、Receive および Send 呼び出しに対してブロッキングを行います。そのため、Csocket および CAysncSocket のソケット タイプはどちらもブロッキング非対応です。ブロッキング非対応のソケットでは、TCP スタックからアプリケーションに FD_READ 通知が送信されて、データがあることが示されます。MFC により、その FD_READ 通知が OnReceive 通知呼び出しに割り当てられます。 Windows ソケットでは、recv 呼び出しの前の FD_READ 通知を無効にするのでない限り、1 つの FD_READ 通知で recv を複数回呼び出すことは避ける必要があります。しかし、CSocket および CAsyncSocket には、通知を無効にするしくみは備わっていません。そのため、Receive 呼び出しは、OnReceive 関数 1 つにつき 1 回だけ実行するようにします。また、データの転送速度が速い環境で、OnReceive 関数内で Receive 呼び出しを複数回実行すると、アプリケーションで FD_READ が認識されなくなり、偽の FD_READ が生成されるか、FD_READ が失われる (ハングする) ことがあります。 CSocket を CArchive および CSocketFile と一緒に使用して、MFC の CObject から派生したオブジェクトを直接受信または送信することができます。しかし、データの転送速度が速い環境では、内部で複数の Receive 呼び出しが生成される可能性があるため、CSocket を CArchive および CSocketFile と一緒に OnReceive 関数内で使用しないようにします。 |
||||||
2. | CAsyncSocket::Send 関数を使用する際に、すべてのデータを送信するために必要な回数の Send 呼び出しを実行しない。 非同期の Send 呼び出しを実行してバッファを送信した場合、実行結果には次の 3 とおりがあります。
3 番目の場合には、TCP/IP スタックでは、さらにバッファ領域を解放すると、MFC により OnSend 通知関数に割り当てられた FD_WRITE 通知をアプリケーションにディスパッチします。この時点でプログラムは、すべてのデータが送信されるか、WSAEWOULDBLOCK が発生するまでデータを送信し続ける必要があります。 OnReceive または OnSend の外部で、CSocket Receive および CSocket Send を使用する (つまり、デフォルトの何も実行しない OnSend および OnReceive を使用する) 場合には、Receive および Send をループで使用することや、CArchive および CSocketFile と一緒に使用することができます。 |
PR
2008/09/26 (Fri.) Trackback() Comment(0) 未選択
Comments
Trackback
Trackback for this entry: