我需要一些帮助来检查是否有人断开连接。目前,我的代码表示每次连接时都会断开连接。我尝试使用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;
}
如何解决这个问题?
答案 0 :(得分:0)
检查send
失败时出现的错误...它可能指向正确的方向(在Windows上使用WSAGetLastError()
)。顺便提一下,你的DissconectThread
只会旋转并咀嚼CPU,直到有连接,然后它会阻塞数据,直到它阻塞一个完整发送缓冲区的连接...可能不是你想要的。
答案 1 :(得分:0)
您需要检查套接字上read()
和write()
次呼叫的返回值(recv()
和send()
相同)。
0
获得read()
,-1
获得write()
,从WSAGetLastError()
获得WSAECONNRESET
。send()
和recv()
获取-1
时的所有其他错误代码,忽略WSAEINTR
之类的内容,关闭所有其他内容。将一些常规的空闲 心跳 纳入 应用级协议 会好得多而不是像你现在那样从专用线程中敲击你的系统。