各模型关闭套接字时机

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完成了。

原文地址:https://www.cnblogs.com/ywledoc/p/2794720.html