0

重複の可能性:
ネットワーク ケーブルが抜かれた場合の検出

誰かが切断されたかどうかを確認するには、助けが必要です。現時点では、私のコードは、接続するたびに誰かが切断したと言っています。send() を使用して、それらがまだ「生きている」かどうかを確認しようとしましたが、正しく行ったかどうかはわかりません。

#pragma comment (lib,"Ws2_32.lib")

#include <iostream>
#include <WinSock2.h>

using namespace std;

#pragma region shittyvars

int countcons = 0, connections[100];
char *dead = new char;
int error;
WSAData netinfo;
int mySocket;
HANDLE acceptth, discth;

#pragma endregion

void AcceptThread( int* a)
{
int clientSocket;
while ( (clientSocket = accept(mySocket,0,0))!=SOCKET_ERROR) 
   connections[countcons++]=clientSocket;
}
void DissconectThread(int*b)
{
for(;;)
  for(int i=0;i<countcons;i++)
   {
       error = send(connections[i],dead,4,0);
 error = WSAGetLastError();
       if(error != 0 )
       {
           closesocket(connections[i]);
           for(int j=i+1 ; j<countcons ;j++)
               connections[j-1]=connections[j];
           countcons--;
           cout<<"\nSomebody disconnected\n";
       }
   }
}

int main() {
#pragma region InitConnection
    error = WSAStartup(MAKEWORD(2,2), &netinfo);

    if (error == SOCKET_ERROR) {
        cout << "Error:Starting socket failed";
        return 1;
    }

    mySocket = socket(AF_INET, SOCK_STREAM, 0);

    if (mySocket == SOCKET_ERROR) {
        cout << "Error:Socket failed to initialize!";
        return 1;
    }
    cout << "Works!";

    struct sockaddr_in server; // network socket struct

    server.sin_family = AF_INET;
    server.sin_port = htons(7654);
    server.sin_addr.s_addr = INADDR_ANY; // Let's us accept any connection

    error = bind(mySocket, (sockaddr*) &server, sizeof(server));

    if (error == SOCKET_ERROR) {
        cout << "Error:Failed to bind socket";
        return 1;
    }

    error = listen(mySocket, 100);

    if (error == SOCKET_ERROR) {
        cout << "Error:The socket is deaf";
        return 1;
    }

#pragma endregion

    acceptth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) AcceptThread,
            &server, 0, (LPDWORD) &acceptth);
    discth = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DissconectThread,
            &server, 0, (LPDWORD) &discth);
    getchar();
    closesocket(mySocket);
    WSACleanup();
    getchar();
    return 0;
}

この問題を解決するにはどうすればよいですか?

4

2 に答える 2

0

ソケットのread()および呼び出しの戻り値を確認する必要があります (およびについても同じです)。write()recv()send()

  • 0から得られる反対側での正常な接続終了についてはread()
  • 突然の切断の場合は、-1からwrite()およびWSAECONNRESETから取得しますWSAGetLastError()
  • および-1からの取得時に他のすべてのエラー コードを確認し、 などを無視して、他のすべてのソケットを閉じます。send()recv()WSAEINTR

現在のように専用スレッドからシステムをドキドキさせるのではなく、定期的なアイドル状態のハートビートアプリケーションレベルのプロトコルに組み込む方がはるかに優れています。

于 2012-11-20T21:20:18.620 に答える
0

失敗したときに表示されるエラーを確認してくださいsend...正しい方向を示している可能性があります(WSAGetLastError()Windowsで使用)。ちなみに、DissconectThread接続が確立されるまでCPUをスピンして噛むだけで、送信バッファーがいっぱいになると1つの接続でブロックされるまでデータが詰まります...おそらく意図したものではありません。

于 2012-11-20T19:58:18.950 に答える