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

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

于 2012-11-20T19:58:18.950 回答
0

您需要检查read()write()调用您的套接字的返回值(和 相同recv()send()

  • 对于另一端的优雅连接终止,您0将从read(),
  • 对于突然断开连接,您-1将从.write()WSAECONNRESETWSAGetLastError()
  • 检查所有其他错误代码,-1然后send()忽略recv()所有其他错误代码,例如WSAEINTR关闭套接字。

将一些常规的空闲心跳合并到您的应用程序级协议中会好得多,而不是像现在这样从专用线程冲击您的系统。

于 2012-11-20T21:20:18.620 回答