私は友人のためにいくつかのコードを見るように頼まれました。(MFCと多くの悪いコードのために躊躇しましたが、彼は勝ちました...)
これは、 を使用するダイアログ ボックス ベースのアプリケーションですCAsyncSocket
。
この問題は、いくつかのノンストップ デバッグ ブレークやその他の同様の現象に現れます。MFC マクロにも問題がありENSURE()
、ソケットの null をチェックします。すべての問題は、MFC の奥深くで発生します。
Vista/XP でテーマを使用するとリソース リークが発生する可能性があることをグーグルで調べたところ、問題はないと思います。
私の数時間のデバッグに基づくと、コードはかなり貧弱ですが、基本的には次のことを行っています。
(接続されている場合は問題ありません。接続されていない場合のみです)
- Connect(server, socket) を呼び出します (派生
CAsyncSocket
オブジェクトで) - で、
OnConnect()
接続が機能しなかった/接続されていないことが通知されます。 - メイン ダイアログ/アプリのウィンドウ タイマー内にタイマーがあります。タイマー イベント/ハンドラーが呼び出されると、接続されているかどうかを確認します。
- 接続されていないことが検出された場合 (これ
OnConnect()
は良くありませんでした)、 を呼び出し、次に (パラメーターなしで) を呼び出しCAsyncSocket::Close()
、次に呼び出しCAsyncSocket::Create()
ますCAsyncSocket::Connect(server, port)
への最初の呼び出しにConnect()
は、 への先行呼び出しがないことに注意してくださいCreate()
。
私の最初の本当の質問:
- 2つの違いは何ですか?なぜ
Create()
必要なのですか?(それを削除するとクラッシュしなくなりますが、接続を再確立しても接続しません)
一般的な質問:
- 上記のコードの設計で正確に間違っているのは何ですか?
- これは一般的にどのように機能する必要がありますか?
編集:
Create()
すべてのパスがthenを呼び出すようにコードを修正しましたConnect()
。
私はまだアサートに問題がありますCAsyncSocket::DoCallBack()
- 以下のコードの最後の行はアサートしています:
void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
{
if (wParam == 0 && lParam == 0)
return;
// Has the socket be closed - lookup in dead handle list
CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE);
// If yes ignore message
if (pSocket != NULL)
return;
pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, FALSE);
if (pSocket == NULL)
{
// Must be in the middle of an Accept call
pSocket = CAsyncSocket::LookupHandle(INVALID_SOCKET, FALSE);
ENSURE(pSocket != NULL);
それをステップスルーすると、メッセージボックスが表示されます:「不適切な引数に遭遇しました」
ソケットを閉じた後、MFC がソケットをコールバックしようとしていると思います (確かではありません)。コールバック メソッド ( )にありますが、ソケットでDoCallback()
既に呼び出しています。Close()
したがって、最初に購読を解除することになっていない限り、MFC の問題のように見えます。