我正在写一个TCP服务器(阻塞套接字模型)。
当服务器正在等待(阻止)接受Accept上的新连接尝试时,我无法实现有效的正常程序退出(我使用WSAccept)。
服务器侦听套接字的代码是这样的(我省略了错误处理和其他不相关的代码):
int ErrCode = WSAStartup(MAKEWORD(2,2), &m_wsaData) ;
// Create a new socket to listen and accept new connection attempts
struct addrinfo hints, *res = NULL, *ptr = NULL ;
int rc, count = 0 ;
memset(&hints, 0, sizeof(hints)) ;
hints.ai_family = AF_UNSPEC ;
hints.ai_socktype = SOCK_STREAM ;
hints.ai_protocol = IPPROTO_TCP ;
hints.ai_flags = AI_PASSIVE ;
CString strPort ;
strPort.Format("%d", Port) ;
getaddrinfo(pLocalIp, strPort.GetBuffer(), &hints, &res) ;
strPort.ReleaseBuffer() ;
ptr = res ;
if ((m_Socket = WSASocket(res->ai_family, res->ai_socktype, res->ai_protocol, NULL, 0, 0)) == INVALID_SOCKET)
{
// some error
}
if(bind(m_Socket, (SOCKADDR *)res->ai_addr, res->ai_addrlen) == SOCKET_ERROR)
{
// some error
}
if (listen(m_Socket, SOMAXCONN) == SOCKET_ERROR)
{
// some error
}
到目前为止一切顺利……然后,我在这样的线程中实现了WSAccept调用:
SOCKADDR_IN ClientAddr ;
int ClientAddrLen = sizeof(ClientAddr) ;
SOCKET TempS = WSAAccept(m_Socket, (SOCKADDR*) &ClientAddr, &ClientAddrLen, NULL, NULL);
当然,WSAccept会阻塞,直到尝试进行新的连接为止,但是如果我希望退出,
该程序然后我需要某种方法来使WSAccept退出。我尝试了几种不同的方法:
我究竟做错了什么 ?
有没有更好的方法来使此阻塞WSAccept退出?
最佳答案
在超时之前使用select()
来检测客户端连接实际上何时挂起,然后再调用WSAAccept()
接受它。它与阻塞套接字一起工作,而无需将它们置于非阻塞模式。这将为您的代码提供更多机会检查应用程序是否已关闭。