完成端口,AcceptEx,DisconnectEx, TIME_WAIT
采用完成端口+AcceptEx+DisconnectEx+线程池+内存池写了一个http server,
我用局域网的几台PC开300线程刷服务器,SOCKET由于过多的TIME_WAIT被耗尽,
然后服务器效率大大降低最后挂掉, 开50线程刷了2天没问题!
TIME_WAIT是TCP协议的一个必经状态,
网上说可以通过SO_LINGER选项让socket不经过TIME_WAIT状态,可是我试了试不行!
谁有解决TIME_WAIT问题的经验,分享一下,谢谢!
//Listener的部分代码
if(pContext->dwIoOper == IO_SOCK_SEND)
{
pChannel->OnSend(dwBytesIo);
if(dwBytesIo <= 0)
{
this->Reset(pChannel, pContext);
}
else if( pChannel->GetResponse()->IoIsComplete() )
{
this->Reset(pChannel, pContext);
/*
// 根据HTTP协议, 通知客户端断开连接
// 即设置HTTP Header为Connection:close
// 然后Receive会接收到0字节关闭消息
// 但是等待客户端关闭效率降低很多
pChannel->GetRequest()->Init();
if(!pChannel->Receive(pContext))
{
this->Reset(pChannel, pContext);
}*/
}
else
{
if(!pChannel->Send(pContext))
{
this->Reset(pChannel, pContext);
}
}
}
//Channel的部分代码
int CHttpChannel::Reset(CompletionPortContext* pContext)
{
int opt = 1;
DWORD dwErrorCode = setsockopt(m_sClientSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
setsockopt(m_sClientSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
//opt = 0;
//nErrorCode = setsockopt(m_sClientSocket, SOL_SOCKET, SO_DONTLINGER, (char*)&opt, sizeof(opt));
linger InternalLinger = { 1, 0 };
dwErrorCode = setsockopt(m_sClientSocket, SOL_SOCKET, SO_LINGER, (const char*)&InternalLinger, sizeof(linger));
shutdown(m_sClientSocket, SD_BOTH);
//closesocket(m_sClientSocket);
//m_sClientSocket = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,WSA_FLAG_OVERLAPPED);
//this->Open(pContext); return 1;
memset(pContext, 0, sizeof(OVERLAPPED));
pContext->dwIoOper = IO_SOCK_CLOSE;
if(MSSOCK::DisconnectEx(m_sClientSocket, pContext, TF_REUSE_SOCKET, 0))
{
printf("DisconnectEx:errorCode=SUCCESS\r\n");
this->Open(pContext);
return 1;
}
else
{
dwErrorCode = WSAGetLastError();
if(dwErrorCode == WSAENOTCONN)
{
printf("DisconnectEx:errorCode=WSAENOTCONN\r\n");
this->Open(pContext);
return 1;
}
else if(dwErrorCode!=ERROR_IO_PENDING)
{
printf("DisconnectEx:errorCode=%d\r\n", WSAGetLastError());
//assert(0);
return -1;
}
}
return 0;
}
我不是新新手,不要拿别人很长的帖子粘贴过来作为回复, 请确信你对解决问题有帮助!