如何检测用户何时断开网络连接?

时间:2012-11-20 19:32:12

标签: c++ sockets winsock

  

可能重复:
  Detect When Network Cable Unplugged

我需要一些帮助来检查是否有人断开连接。目前,我的代码表示每次连接时都会断开连接。我尝试使用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;
}

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

检查send失败时出现的错误...它可能指向正确的方向(在Windows上使用WSAGetLastError())。顺便提一下,你的DissconectThread只会旋转并咀嚼CPU,直到有连接,然后它会阻塞数据,直到它阻塞一个完整发送缓冲区的连接...可能不是你想要的。

答案 1 :(得分:0)

您需要检查套接字上read()write()次呼叫的返回值(recv()send()相同)。

  • 为了在另一方面终止优雅连接,您将从0获得read()
  • 对于突然断开连接,您将从-1获得write(),从WSAGetLastError()获得WSAECONNRESET
  • 检查从send()recv()获取-1时的所有其他错误代码,忽略WSAEINTR之类的内容,关闭所有其他内容。

将一些常规的空闲 心跳 纳入 应用级协议 会好得多而不是像你现在那样从专用线程中敲击你的系统。