1.select
readfds集合有下列事件发生时,会被标识:
数据可读;连接已经关闭、重启或者中断;如果listen已经调用,并且有一个连接未决,accept可以成功。
select函数会返回,有多少个socket发生了事件。
要关闭一个套接字时,判断select返回>0,然后recv套接字,出错,就代表这个socket可以closesocket了。
2.WSAAsyncSelect
int WSAAsyncSelect(
SOCKET s,
HWND hWnd,
unsigned int wMsg,
long lEvent
);
第四个参数lEvent,可以设置FD_CLOSE
当有socket被关闭时,会发送一条这个消息
3.WSAEventSelect
int WSAEventSelect(
SOCKET s,
WSAEVENT hEventObject,
long lNetworkEvents
);
第三个参数也可以设置FD_CLOSE
然后
int WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
);
的第三个参数指明了是不是发生了FD_CLOSE
WSANETWORKEVENTS event;
::WSAEnumNetworkEvents(pSocket->s, pSocket->event, &event);
else if(event.lNetworkEvents & FD_CLOSE) // 套节字关闭
{
m_fnNotifyProc(pSocket, pThread, NC_DISCONNECT);
break;
}
4.重叠IO
BOOL WSAGetOverlappedResult(
SOCKET s,
LPWSAOVERLAPPED lpOverlapped,
LPDWORD lpcbTransfer,
BOOL fWait,
LPDWORD lpdwFlags
);
这个函数出错了,就代表socket出错了
5.IO完成端口
BOOL GetQueuedCompletionStatus(
HANDLE CompletionPort,
LPDWORD lpNumberOfBytes,
PULONG_PTR lpCompletionKey,
LPOVERLAPPED* lpOverlapped,
DWORD dwMilliseconds
);
这个MSDN上就有解释
If a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS, with *lpOverlapped non-NULL and lpNumberOfBytes equal zero.
顺便说下,这5种模型有意思的区别
以本文顺序来说
前三种,是等待事件,然后再发送一个IO(recv,accept)。
后二种,是先发一个IO,再等待事件,表示IO完成了。