我有以下代码,我不知道为什么它不能正常工作。
它是一个多线程TCP服务器,它循环accept()调用并触发指定的
每次线程。
问题是接受有时不会阻塞,从而产生
当理论上没有连接时打开新线程的程序。
这就是循环 -
for (dwI = 0;; dwI++) //Accept MAX_CLIENTS connections
{
if(MAX_CLIENTS == dwI)
{
dwI=0;
continue;
}//if
if(clients[dwI].bIsInUse)
{
continue;
}//if
ZeroMemory(&from,sizeof(from));
if(!AcceptConnection(&ServerSock,&from,&ClientSock))
{
PRINT_LE("AcceptConnection",ERROR_ACCEPT_SERVER_CONNECTION);
closesocket(ServerSock);
WSACleanup();
return EXIT_FAILURE;
}//if
clients[dwI].ClientSock = ClientSock;
if(! (clients[dwI].hThread = CreateThread(
NULL, //Not inheritable
0, //Default stack size
ThreadedAcceptTCP, //ThreadedAccept - function
&clients[dwI],//Pass pointer to the socket
0, //Start immidiately
&clients[dwI].dwThreadId //Save thread id
)))
{
PRINT_GLE("CreateThread");
closesocket(ServerSock);
WSACleanup();
return EXIT_FAILURE;
}//if
#ifdef PRINT_STATUS //Print status if macro is defined
printf("Server responce message has been sent.\n");
#endif
}//for
使用我自己的每个函数的包装器。
AcceptConnection的代码如下 -
SOCKET ClientSocket = INVALID_SOCKET; //Client socket
INT sockaddrSize = sizeof(*pSockAddr);
ClientSocket = accept( //Create client accepting socket
*pSock, //Listen-ed socket
pSockAddr,
&sockaddrSize
);
if (INVALID_SOCKET == ClientSocket) //Check for errors - if any - cleanup and return failure
{
PRINT_WSAGLE("socket");
return FAILURE;
}//if
*pClientSock = ClientSocket; //Pass socket
return SUCCESS;
当我通过浏览器连接到服务器时出现问题
例如,
第一个线程完成后的(我通过暂停主线程5秒来确保这一点)
它清理所有内容并关闭客户端套接字,
虽然在第二次接受电话会议上 - 它将以相同的
返回SOCKADDR信息并导致额外的线程上升,
接收完全相同的数据,发送完全相同的数据。
打印2次(有时甚至更多次):
“已发送服务器响应消息。”
我无法弄清楚为什么会发生这种情况,希望你们能帮助我。
谢谢!
答案 0 :(得分:0)
这是一个猜测,但我想知道这行代码中的逻辑:
if(!AcceptConnection(&ServerSock,&from,&ClientSock))
期望AcceptConnection
在成功时返回非零值,在失败时返回零值。但是,该函数成功时返回常量SUCCESS
。但是,某些Windows头文件将常量SUCCESS定义为0.并且各种失败常量都是非零值。
即使您在自己的代码中定义了SUCCESS和FAILURE,也可以专门检查返回值,例如:
if (FAILURE == AcceptConnection(&ServerSock,&from,&ClientSock))
答案 1 :(得分:0)
一个可能的问题:在分配新的客户端SOCKET之后看起来你没有将clients[dwI].bIsInUse
设置为true,这会在你的for循环中弄乱你的逻辑。