none
Winsock2で接続断を検知する方法はないのでしょうか? RRS feed

  • 質問

  • 表題の件なのですが、方法がわからず困っています。

    また接続中にクライアント側のLANケーブルを引っこ抜くと、システムがフリーズしてしまいます。

    なにか良い方法をご存知の方、教えてください。

    2008年6月6日 5:37

回答

  • システムがフリーズとは穏やかではないですね。

     

    接続が切れたら普通はエラーが返ってきます。

    そうでないなら、システムに何か問題があると思います。

    2008年6月6日 7:02
  •  Barkmann さんからの引用

    > OSがフリーズするのかと思いましたが、違うようですね。
    > アプリケーションがフリーズしているだけではないですか?

     

    TCPクライアント側は、ケーブルを抜くとマウスカーソルが固まります。キーボードも受け付けなくなります。ケーブルを戻すと復帰します。固まっている間にマウスを動かしていると、その場所で復帰するので、OSの一部がフリーズしているように思えます。

     

    まだ状況がよく飲み込めていないのですが、ケーブルを抜くとOSがフリーズするという現象は以下のどの時に発生するのでしょうか?

    1.OS起動後、何もしていない状態でケーブルを抜く

    2.作成したアプリを起動した状態でケーブルを抜く

    3.作成したアプリが通信中にケーブルを抜く

    4.作成したアプリ以外のアプリ(例えばIEでダウンロード中や共有ファイルをコピーするなど)が通信中にケーブルを抜く

     

    1や4でも発生するのであればOSが何かしらの異常な状態になっているのでOSの修復が必要です。

     

    2008年6月12日 12:14
  •  Barkmann さんからの引用

    TCPサーバー側はacceptの正常終了の後、ケーブルを抜くとFD_CLOSEイベントが発生してソケットを閉じることができます。



    横から失礼します。
    accept が完了しただけの状態では FD_CLOSE を受け取ったり出来ないように思うのですが。

    例えば、切断が検知できるのは以下のようなケースではないでしょうか?

    -----------------------------
    accept
       ↓
    他の処理
       ↓  ← ここで切断される
    他の処理
       ↓
    recv  → ここでエラーになる。
    -----------------------------

    つまり、何らかのソケット対してアクションをおこなわないと
    切断されたことはわからないのでは。


    上記以外で言えば、サーバ側が select していると
    select が反応して select の次の処理に進みます。
    この時点では select が正常に受信して抜けたのか
    エラーで抜けたのかはわかりません。
    通常、select の後に recv などをしていて、
    recv でエラーになります。

    // マウスが固まったりするのはわからないですねぇ。
    // もしかしてクライアント側って Windows メッセージをブロックするような処理をしてます?
    2008年6月16日 9:06
  • Windowメッセージベースで実装されているようなので、
    OSが固まるというのはWindowメッセージが正常に処理されなくなって
    固まっているのではないかと思います。

    処理のいたるところにログを仕込んで調べてみるのはいかがでしょうか?
    ログをテキスト出力するようにして、そのログに時間を付加しておけば
    ブロック前とブロック後で時間の空いたログが出るのでブロックされている箇所がわかると思います。

    2008年6月17日 11:00

すべての返信

  • システムがフリーズとは穏やかではないですね。

     

    接続が切れたら普通はエラーが返ってきます。

    そうでないなら、システムに何か問題があると思います。

    2008年6月6日 7:02
  • お返事ありがとうございます。 

     

    > システムがフリーズとは穏やかではないですね。

     

    フリーズしない時もあります。一体何に問題があるのかわからず困っています。

     

    > 接続が切れたら普通はエラーが返ってきます。

    > そうでないなら、システムに何か問題があると思います。

     

    私はケーブルが抜けたら FD_CLOSE イベントが発生すると思っていたのですが、違うのです。

    サーバー側のケーブルを抜いた場合は FD_CLOSE が発生するのですが。

     

    ちなみに環境はWindows XP Professional SP2 です。

    LANケーブルを抜き差しすると、画面右下にバルーンとアイコンが出ますが、あれはWinsockでやってるのではないのでしょうか?

     

    2008年6月6日 7:37
  •  Barkmann さんからの引用

    サーバー側のケーブルを抜いた場合は FD_CLOSE が発生するのですが。

     

    OSがフリーズするのかと思いましたが、違うようですね。

    アプリケーションがフリーズしているだけではないですか?

     

     Barkmann さんからの引用

    私はケーブルが抜けたら FD_CLOSE イベントが発生すると思っていたのですが、違うのです。

     

    違います。

     

    TCPだと仮定して話をしますが、

    接続後、Socketにはサーバーもクライアントもありません。対称です。

    片方が切断を検地できて、片方が出来ない、ということはデータの流れが非対称だからですよね。

     

    切断を知ることができるほうは、能動的に動いている方、つまり送信側でしょうね。

    相手がいないから送れない。

     

    反対に、知ることが出来ないほうは受信側ですね。

    いつまでもデータが送られるのを待っている。

     

    TCPでは、keepaliveという機構で相手が繋がっているか確認しますが、

    これが既定では2時間くらいになっています。

    2時間待てば、エラーが返ってくると思います。

     

    もちろんそれじゃ使い物になりませんので、いろいろ工夫します。

    その辺は、TCP/IPの基礎やSocketの基礎を学ぶ際にかならず出てくる事項ですので、

    本などで勉強するといいでしょう。

     

    一からここで説明するのは大変です。

     

     Barkmann さんからの引用

    LANケーブルを抜き差しすると、画面右下にバルーンとアイコンが出ますが、あれはWinsockでやってるのではないのでしょうか?

    あれはWinsockよりも下位のレベルのモジュールがやっています。

    ネットワークのクラスドライバだと思います。

    WinsockやTCPの層は

    「LANケーブルが刺さっているかどうか」を意識することはありません。

    「論理的に繋がっているかどうか」しか見ていません。

     

    この辺も、ネットワークの基礎ですから、本などで勉強するといいでしょう。

     

     

    2008年6月6日 8:01
  • レスありがとうございます。遅くなってしまって済みません。

     

    > OSがフリーズするのかと思いましたが、違うようですね。
    > アプリケーションがフリーズしているだけではないですか?

     

    TCPクライアント側は、ケーブルを抜くとマウスカーソルが固まります。キーボードも受け付けなくなります。ケーブルを戻すと復帰します。固まっている間にマウスを動かしていると、その場所で復帰するので、OSの一部がフリーズしているように思えます。

     

    > 違います。
    > TCPだと仮定して話をしますが、
    > 接続後、Socketにはサーバーもクライアントもありません。対称です。
    > 片方が切断を検地できて、片方が出来ない、ということはデータの流れが非対称だからですよね。
    >
    > 切断を知ることができるほうは、能動的に動いている方、つまり送信側でしょうね。
    > 相手がいないから送れない。
    >
    > 反対に、知ることが出来ないほうは受信側ですね。
    > いつまでもデータが送られるのを待っている。

     

    問題なのは send() がケーブルが抜かれた状態でもエラーにならないのです。

     

    > TCPでは、keepaliveという機構で相手が繋がっているか確認しますが、
    > これが既定では2時間くらいになっています。
    > 2時間待てば、エラーが返ってくると思います。
    >
    > もちろんそれじゃ使い物になりませんので、いろいろ工夫します。
    > その辺は、TCP/IPの基礎やSocketの基礎を学ぶ際にかならず出てくる事項ですので、
    > 本などで勉強するといいでしょう。

     

    まだWinsockを使い始めて1ヶ月程度の初心者なもので、色々と済みません。
    一応、『猫でもわかるネットワークプログラミング/粂井康孝 著』、『Winsock2.0プログラミング/Lewis Napper 著』などを読んで勉強はしているのですが…。
    ちなみに、この『猫…』のTCPサーバー/クライアントのサンプルプログラムでも、クライアントのケーブルを抜くと同様な現象が起こります。

     

    > 一からここで説明するのは大変です。

     

    それは十分承知しております。
    もしなにか良い本をご存知でしたら、教えていただけると幸いです。

     

    > あれはWinsockよりも下位のレベルのモジュールがやっています。
    > ネットワークのクラスドライバだと思います。
    > WinsockやTCPの層は
    > 「LANケーブルが刺さっているかどうか」を意識することはありません。
    > 「論理的に繋がっているかどうか」しか見ていません。
    >
    > この辺も、ネットワークの基礎ですから、本などで勉強するといいでしょう。

     

    これも良い本がなかなかみつかりません。何かご存知でしたら教えていただけないでしょうか。

     

    色々と説明ありがとうございます。
    わからないことだらけで、色々質問してしまって済みませんです。

    2008年6月10日 5:18
  •  Barkmann さんからの引用

    > OSがフリーズするのかと思いましたが、違うようですね。
    > アプリケーションがフリーズしているだけではないですか?

     

    TCPクライアント側は、ケーブルを抜くとマウスカーソルが固まります。キーボードも受け付けなくなります。ケーブルを戻すと復帰します。固まっている間にマウスを動かしていると、その場所で復帰するので、OSの一部がフリーズしているように思えます。

     

    まだ状況がよく飲み込めていないのですが、ケーブルを抜くとOSがフリーズするという現象は以下のどの時に発生するのでしょうか?

    1.OS起動後、何もしていない状態でケーブルを抜く

    2.作成したアプリを起動した状態でケーブルを抜く

    3.作成したアプリが通信中にケーブルを抜く

    4.作成したアプリ以外のアプリ(例えばIEでダウンロード中や共有ファイルをコピーするなど)が通信中にケーブルを抜く

     

    1や4でも発生するのであればOSが何かしらの異常な状態になっているのでOSの修復が必要です。

     

    2008年6月12日 12:14
  • C.Johnさん、レスありがとうございます。

    フリーズするのは(3)の状態です。通信中と言っても、ソケットが接続されているだけで、データの送受信はしていません。

    TCPクライアントでconnectが正常終了した状態です。

    TCPサーバー側はacceptの正常終了の後、ケーブルを抜くとFD_CLOSEイベントが発生してソケットを閉じることができます。

    クライアント側だと、どうしてフリーズしてしまうのか分かりません。ケーブルを戻すと復帰しますが、サーバー側がソケットを閉じているのにsendが正常終了するのもどうしてかわかりません。

     

    何かお知恵を貸していただけると幸いです。

     

    2008年6月12日 14:38
  •  Barkmann さんからの引用

    TCPサーバー側はacceptの正常終了の後、ケーブルを抜くとFD_CLOSEイベントが発生してソケットを閉じることができます。



    横から失礼します。
    accept が完了しただけの状態では FD_CLOSE を受け取ったり出来ないように思うのですが。

    例えば、切断が検知できるのは以下のようなケースではないでしょうか?

    -----------------------------
    accept
       ↓
    他の処理
       ↓  ← ここで切断される
    他の処理
       ↓
    recv  → ここでエラーになる。
    -----------------------------

    つまり、何らかのソケット対してアクションをおこなわないと
    切断されたことはわからないのでは。


    上記以外で言えば、サーバ側が select していると
    select が反応して select の次の処理に進みます。
    この時点では select が正常に受信して抜けたのか
    エラーで抜けたのかはわかりません。
    通常、select の後に recv などをしていて、
    recv でエラーになります。

    // マウスが固まったりするのはわからないですねぇ。
    // もしかしてクライアント側って Windows メッセージをブロックするような処理をしてます?
    2008年6月16日 9:06
  •  Barkmann さんからの引用

    これも良い本がなかなかみつかりません。何かご存知でしたら教えていただけないでしょうか。

     

    本は知りません。

    Webサイトであれば http://tangentsoft.net/wskfaq/ などがよいと思います。

     

     Barkmann さんからの引用

    TCPクライアント側は、ケーブルを抜くとマウスカーソルが固まります。キーボードも受け付けなくなります。ケーブルを戻すと復帰します。固まっている間にマウスを動かしていると、その場所で復帰するので、OSの一部がフリーズしているように思えます。

     

    うーん。説明がよくわかりません。

     

    他のアプリケーションも止まるのでしょうか?

    「その場所で復帰」の「その」とはどこでしょう?

    該当クライアントだけbusy状態になる、というわけではないのでしょうか?

     

    もし、本当にOSがフリーズするのであれば

    ネットワークドライバを再インストールしたり、

    OSを再インストールしたほうがよいでしょう。

    2008年6月16日 10:21
  • iversionjp さん、レスありがとうございます。

     

    説明不足でした。FD_CLOSEが発生するのはaccept直後にWSAAsyncSelectでFD_CLOSEをしているからと勝手に思い込んでいるんですが、違うのでしょうか。

    面倒なので、ウィンドウプロシージャ全部ここに載せます。ざっと見ておかしなところがあったら指摘してくださればありがたいです。

     

    //-----------------------------------------------------------------------------
    // WM_CREATE
    static LRESULT Socket_OnCreate (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
     HIPLSOCKET hSock = (HIPLSOCKET)lpcs->lpCreateParams;
     WSADATA wsaData;
     int ret;

     if(hSock == NULL) return -1;/**/

     SetWindowLong(hwnd, 0, (LONG)hSock);

     ret = WSAStartup(WINSOCK_VERSION, &wsaData);// Winsock 2.0
     if(ret != 0)
     {
         /* Tell the user that we could not find a usable */
         /* WinSock DLL.                                  */
         return -1;
     }

     if(hSock->dwFlags & IPL_SOCKET_SERVER)
     {
      // server
      // listen socket を開く
      hSock->listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      if(hSock->listenSocket == INVALID_SOCKET) return -1;

      // bind
      ((LPSOCKADDR_IN)(&hSock->saServer))->sin_family = AF_INET;
      ((LPSOCKADDR_IN)(&hSock->saServer))->sin_port = htons((WORD)hSock->nPort);
      ((LPSOCKADDR_IN)(&hSock->saServer))->sin_addr.s_addr = INADDR_ANY;
      ret = bind(hSock->listenSocket, &hSock->saServer, sizeof(struct sockaddr));
      if(ret == SOCKET_ERROR)
      {
       int err = WSAGetLastError();
       closesocket(hSock->listenSocket);
       hSock->listenSocket = INVALID_SOCKET;
       return -1;/**/
      }
      ret = listen(hSock->listenSocket, SOMAXCONN);
      if(ret == SOCKET_ERROR)
      {
       closesocket(hSock->listenSocket);
       hSock->listenSocket = INVALID_SOCKET;
       return -1;/**/
      }
      if(SOCKET_ERROR == WSAAsyncSelect(hSock->listenSocket, hwnd, WM_LISTEN_EVENT, FD_ACCEPT | FD_CLOSE))
       return -1;
     }
     else
     {
      ULONG addr;
      LINGER ling;
      // client
      hSock->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      if(hSock->socket == INVALID_SOCKET) return -1;/**/

      memset(&ling, 0, sizeof(LINGER));
      ling.l_onoff = TRUE;
      ling.l_linger = 0;
      setsockopt(hSock->socket, SOL_SOCKET, SO_LINGER, (LPTSTR)&ling, sizeof(ling));

      if(SOCKET_ERROR == WSAAsyncSelect(hSock->socket, hwnd, WM_CLIENT_EVENT, FD_CONNECT | FD_CLOSE | FD_READ))
       return -1;

      ((LPSOCKADDR_IN)(&hSock->saServer))->sin_family = AF_INET;
      ((LPSOCKADDR_IN)(&hSock->saServer))->sin_port = htons((WORD)hSock->nPort);
      addr = inet_addr(hSock->szServerName);
      if(addr == INADDR_NONE)
      {
       LPHOSTENT lpHostEnt;
       lpHostEnt = gethostbyname(hSock->szServerName);
       if(lpHostEnt == NULL)
       {
        int err = WSAGetLastError();
        return -1;// サーバーが見つからない
       }
       addr = *(LPLONG)lpHostEnt->h_addr;
       if(addr == 0) return -1;
      }
      ((LPSOCKADDR_IN)&hSock->saServer)->sin_addr.s_addr = addr;

      if(SOCKET_ERROR == connect(hSock->socket, &hSock->saServer, sizeof(SOCKADDR_IN)))
      {
       int err = WSAGetLastError();
       if(err != WSAEWOULDBLOCK) return -1;
      }
     }

     return 0;
    }

    //-----------------------------------------------------------------------------
    // WM_DESTROY
    static LRESULT Socket_OnDestroy (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     HIPLSOCKET hSock;

     hSock = (HIPLSOCKET)GetWindowLong(hwnd, 0);
     if(hSock == NULL) return 0;

     if(hSock->dwFlags & IPL_SOCKET_SERVER)
     {
      WSAAsyncSelect(hSock->listenSocket, hwnd, 0, 0);
      closesocket(hSock->listenSocket);
      hSock->listenSocket = INVALID_SOCKET;
     }

     WSAAsyncSelect(hSock->socket, hwnd, 0, 0);
     closesocket(hSock->socket);
     hSock->fConnect = 0;
     hSock->fRead = 0;
     hSock->socket = INVALID_SOCKET;

     WSACleanup();

     memset(hSock, 0, sizeof(IPLSOCKET));
    // hSock->hwnd = NULL;
     free(hSock);
     
     return 0;
    }

    //-----------------------------------------------------------------------------
    //
    static LRESULT Socket_OnListenEvent (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     HIPLSOCKET hSock;
     int nEventCode = WSAGETSELECTEVENT(lParam);
     int nErrorCode = WSAGETSELECTERROR(lParam);
     int len;
     LINGER ling;

     hSock = (HIPLSOCKET)GetWindowLong(hwnd, 0);

     switch(nEventCode)
     {
     case FD_ACCEPT:
      if(hSock->fConnect) break;// 接続済み

      len = sizeof(SOCKADDR_IN);
      hSock->socket = accept(hSock->listenSocket, (SOCKADDR *)&hSock->saClient, &len);
      if(hSock->socket == INVALID_SOCKET) break;

      memset(&ling, 0, sizeof(LINGER));
      ling.l_onoff = TRUE;
      ling.l_linger = 0;
      setsockopt(hSock->socket, SOL_SOCKET, SO_LINGER, (LPTSTR)&ling, sizeof(ling));

      if(SOCKET_ERROR == WSAAsyncSelect(hSock->socket, hwnd, WM_SERVER_EVENT, FD_CLOSE | FD_READ))
      {
       shutdown(hSock->socket, SD_BOTH);
       closesocket(hSock->socket);
       hSock->socket = INVALID_SOCKET;
       break;
      }
      hSock->fConnect = TRUE;
      SendMessage(GetParent(hwnd), WM_SOCKET_ACCEPT, 0, lParam);
      break;

     case FD_CLOSE:
      hSock->fConnect = FALSE;

      shutdown(hSock->socket, SD_BOTH);
      closesocket(hSock->socket);
      hSock->socket = INVALID_SOCKET;

      closesocket(hSock->listenSocket);

      SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
      DestroyWindow(hwnd);

      break;
     }
     return 0;
    }

    //-----------------------------------------------------------------------------
    //
    static LRESULT Socket_OnServerEvent (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     HIPLSOCKET hSock;
     int nEventCode = WSAGETSELECTEVENT(lParam);
     int nErrorCode = WSAGETSELECTERROR(lParam);

     hSock = (HIPLSOCKET)GetWindowLong(hwnd, 0);

     switch(nEventCode)
     {
     case FD_CLOSE:
      hSock->fConnect = FALSE;

      shutdown(hSock->socket, SD_BOTH);
      closesocket(hSock->socket);
      hSock->socket = INVALID_SOCKET;
      SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
      DestroyWindow(hwnd);
      break;
     case FD_READ:// データ受信可
      if(nErrorCode != 0)
      {
       hSock->fConnect = FALSE;
       SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
       DestroyWindow(hwnd);
      }
      hSock->fRead = TRUE;
      SendMessage(GetParent(hwnd), WM_SOCKET_READ, 0, lParam);
      break;
     }
     return 0;
    }

    //-----------------------------------------------------------------------------
    //
    static LRESULT Socket_OnClientEvent (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     HIPLSOCKET hSock;
     int nEventCode = WSAGETSELECTEVENT(lParam);
     int nErrorCode = WSAGETSELECTERROR(lParam);

     hSock = (HIPLSOCKET)GetWindowLong(hwnd, 0);

     switch(nEventCode)
     {
     case FD_CONNECT:
      switch(nErrorCode)
      {
      case WSAEADDRNOTAVAIL:
       SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
       DestroyWindow(hwnd);
       return 0;
      case 0:
       break;
      case WSAETIMEDOUT:
       SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
       DestroyWindow(hwnd);
       return 0;
      case WSAECONNREFUSED:
       SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
       DestroyWindow(hwnd);
       return 0;
      default:
       SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
       DestroyWindow(hwnd);
       return 0;
      }
      hSock->fConnect = TRUE;
      SendMessage(hwnd, WM_CONNECT_EVENT, 0, 0);
      SendMessage(GetParent(hwnd), WM_SOCKET_CONNECT, 0, 0);
      break;
     case FD_CLOSE:
      hSock->fConnect = FALSE;
      SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
      DestroyWindow(hwnd);
      break;
     case FD_READ:
      if(nErrorCode != 0)
      {
       hSock->fConnect = FALSE;
       SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam);
       DestroyWindow(hwnd);
       break;
      }
      hSock->fRead = TRUE;
      SendMessage(GetParent(hwnd), WM_SOCKET_READ, 0, lParam);
      break;
     }
     return 0;
    }

    //-----------------------------------------------------------------------------
    //
    static LRESULT Socket_OnConnectEvent (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     HIPLSOCKET hSock = (HIPLSOCKET)GetWindowLong(hwnd, 0);

     hSock->fConnect = TRUE;

     return 0;
    }

    //-----------------------------------------------------------------------------
    //
    static LRESULT CALLBACK SocketWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
     switch(uMsg)
     {
     case WM_SERVER_EVENT:
      return Socket_OnServerEvent(hwnd, uMsg, wParam, lParam);
     case WM_CLIENT_EVENT:
      return Socket_OnClientEvent(hwnd, uMsg, wParam, lParam);
     case WM_LISTEN_EVENT:
      return Socket_OnListenEvent(hwnd, uMsg, wParam, lParam);
     case WM_CONNECT_EVENT:
      return Socket_OnConnectEvent(hwnd, uMsg, wParam, lParam);
     case WM_CREATE:
      return Socket_OnCreate(hwnd, uMsg, wParam, lParam);
     case WM_DESTROY:
      return Socket_OnDestroy(hwnd, uMsg, wParam, lParam);
     }
     return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

    2008年6月17日 6:35
  • れいさん、レスありがとうございます。
    紹介してくださったWebサイトを見てみますね。

     

    >うーん。説明がよくわかりません。
    >他のアプリケーションも止まるのでしょうか?
    >「その場所で復帰」の「その」とはどこでしょう?
    >該当クライアントだけbusy状態になる、というわけではないのでしょうか?

     

    説明が下手で済みません。とにかくクライアント側はケーブルを抜くとマウスカーソルが動かなくなってしまうのです。
    「猫でもわかるネットワークプログラミング」という本の、TCPクライアントも同様な現象が起こります。
    Win2KのPCでもXPのPCでも同様の現象が起こるので、OSやドライバではなく、アプリケーション側に問題があるのは確かだと思いますが…。

    2008年6月17日 7:04
  • Windowメッセージベースで実装されているようなので、
    OSが固まるというのはWindowメッセージが正常に処理されなくなって
    固まっているのではないかと思います。

    処理のいたるところにログを仕込んで調べてみるのはいかがでしょうか?
    ログをテキスト出力するようにして、そのログに時間を付加しておけば
    ブロック前とブロック後で時間の空いたログが出るのでブロックされている箇所がわかると思います。

    2008年6月17日 11:00
  • レスありがとうございます。

    マスウカーソルが動かなくなり、Alt+Ctrl+Delでタスクマネージャを起動することもできないので、Winsockのブロッキング現象なんでしょうか…。

     

    >処理のいたるところにログを仕込んで調べてみるのはいかがでしょうか?
    >ログをテキスト出力するようにして、そのログに時間を付加しておけば
    >ブロック前とブロック後で時間の空いたログが出るのでブロックされている箇所がわかると思います。

    やっぱり、もうそれしかないでしょうか。コツコツでやるしかなさそうですね。

    原因がわかったら報告します。

    2008年6月23日 5:43
  • ログ出力を付けてみたんですが、そうしたらフリーズが発生しなくなりました…。
    一体何が原因なのかわかりません。

    とりあえず、LANケーブルが抜けた側は FD_CLOSE イベント発生により回線断検知。
    相手側は send() がエラーになり、
    回線断検知ができる、ということはわかりました。

    2008年7月16日 9:10
  • こんにちは、フォーラムオペレータ大久保です。

     

    うーん、ログ記録の機能を追加したら現象が発生しなくなったと…困りましたね。

    根本的な解決をお望みでしたら有償サポートを利用するというテもあるんでしょうが、おそらく Baarkmann さんの目的はそこではないと思いますので、このまま様子をみていただくのがいいかもしれないですね。

    # 昔 VB2.0 の頃でしたが、コメント行を追加したらそれまで出ていた一般保護違反が出なくなった、とかよく遭遇しました。

     

    今回、多くの皆様からアドバイスをいただきましたので、まことに勝手ながら皆様の投稿に「回答済み」チェックをつけさせていただきました。

    その後、なにかお分かりのことがありましたら情報をいただければと思います。

     

    それでは

    2008年7月25日 9:53
  • ログ出力を付けてみたんですが、そうしたらフリーズが発生しなくなりました…。
    一体何が原因なのかわかりません。

    とりあえず、LANケーブルが抜けた側は FD_CLOSE イベント発生により回線断検知。
    相手側は send() がエラーになり、
    回線断検知ができる、ということはわかりました。

    随分古いスレッドですが、たどり着いてしまったので・・・後続の方のために案をひとつ。

    closesocket()とか、SendMessage(GetParent(hwnd), WM_SOCKET_CLOSE, 0, lParam); の後片付けが完了する前に、DestroyWindow(hwnd); によって不正に中断されているとか、ないですかね。

    (全体プロセスを終了するのは、リソースの破棄が全て完了してからやらないと、予期せぬ何かが起きたりする。)



    2021年2月10日 12:06