1)Listen:
listen socket,通过setsockopt设置SO_REUSEADDR选项,表示:如果已经处于ESTABLISHED状态下的socket调用了closesocket(一般不会立即关闭而是经历TIME_WAIT的过程)后想继续重用该socket。示例代码:
reuseAddr = 1;
ret = setsockopt(m_listenSo,
SOL_SOCKET,
SO_REUSEADDR,
(const char*)&reuseAddr,
sizeof(int));
2)Accept:
Windows:示例代码:
acceptEvent = WSACreateEvent();
HANDLE events[2];
events[0] = acceptEvent;
while(1)
{
if (WSAEventSelect(socket, acceptEvent, FD_ACCEPT) == SOCKET_ERROR)
{
//DO SOMETHING
}
ret = WSAWaitForMultipleEvents(numOfEvents, events, FALSE, INFINITE, FALSE);
if ( ret == WSA_WAIT_OBJECT_0 )
{
sock = accept(socket,xxx,xxx);
if (INVALID_SOCKET == sock)
{
if(WSAEWOULDBLOCK == WSAGetLastError())
{
WSAResetEvent(acceptEvent);
continue;
}
}
else
{
WSAResetEvent(m_acceptEvent);
//connect ok
}
}
}
}
Linux 示例代码:
sock = accept();
if (sock < 0)
{
//do something
}
else
{
//ok
}
Windows: 示例代码:
if ( (so = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) //do something
if ( (n = connect(so, (struct sockaddr*)&serverAddr, sizeof(serverAddr))) < 0 )
{
//do something
}
else
{
//("Connect ok\n");
}
Linux:示例代码:
if ( (so = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
//do something
}
if ( (n = connect(so, (struct sockaddr*)&serverAddr, sizeof(serverAddr))) < 0 )
{
if ( errno != EINPROGRESS )
{
//do something
}
}
/* 连接成功 */
if ( n == 0 )
{
//do something
}
else
{
//in progress, 等待socket
fd_set rset, wset;
struct timeval tv;
int selectRet;
FD_ZERO(&rset);
FD_ZERO(&wset);
wset = rset;
if ( timeout != 0 )
{
tv.tv_sec = (timeout / 1000);
tv.tv_usec = (timeout % 1000) * 1000;
}
do
{
selectRet = select(so + 1, &rset, &wset, NULL,
timeout != 0 ? &tv, NULL);
} while ( selectRet < 0 && errno == EINTR );
if ( selectRet < 0 )
{
//do something
}
else if ( selectRet == 0 ) //timeout
{
//do something
}
if ( FD_ISSET(so, &rset) || FD_ISSET(so, &wset) )
{
int sockError;
socklen_t soptLen;
soptLen = sizeof(sockError);
if ( getsockopt(so, SOL_SOCKET, SO_ERROR, &sockError, &soptLen) == 0 &&
sockError == 0 )
{
/* 连接成功 */
//do something
}
else
{
//do something
}
}
}