Reputation: 1031
I'm trying to get FD_CLOSE event (c++) by WSAWaitForMulipleObjects. in the WSASelectEvent I've set only the FD_CLOSE. however, the wait return, and the network enumaration also return 0, but NetworkEvents return 0 from the enumaration so I can't see FD_CLOSE in it.
Any help?
thanks.
void EventThread(void* obj)
{
WSANETWORKEVENTS NetworkEvents;
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
DWORD EventTotal = 0;
EventArray[EventTotal] = WSACreateEvent();
EventTotal++;
int res;
int index;
if(WSAEventSelect(_socket, EventArray[EventTotal - 1], FD_CLOSE)==SOCKET_ERROR)
Logger::GetInstance() << "WSAEventSelect failed with error " << WSAGetLastError() << endl;
bool bResult;
while(true)
{
if((index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE))==WSA_WAIT_FAILED)
{
Logger::GetInstance() << "WSAWaitForMultipleEvents failed with error " << WSAGetLastError() << endl;
}
if ((index != WSA_WAIT_FAILED) && (index != WSA_WAIT_TIMEOUT)) {
res = WSAEnumNetworkEvents(_socket, EventArray[index - WSA_WAIT_EVENT_0], &NetworkEvents) ;
if(NetworkEvents.lNetworkEvents & FD_CLOSE)
{
if(NetworkEvents.iErrorCode[FD_CLOSE_BIT] !=0)
{
Logger::GetInstance() << "FD_CLOSE failed with error " << NetworkEvents.iErrorCode[FD_CLOSE_BIT] << endl;
}
else
{
Logger::GetInstance() << "FD_CLOSE is OK!!! " << NetworkEvents.iErrorCode[FD_CLOSE_BIT] << endl;
}
}
}
}
}
Upvotes: 1
Views: 3960
Reputation: 596672
The WinSock documentation says the following:
The
FD_CLOSE
message is posted when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that theFD_CLOSE
is posted when the connection goes into theTIME_WAIT
orCLOSE_WAIT
states. This results from the remote end performing ashutdown()
on the send side or aclosesocket()
.FD_CLOSE
should only be posted after all data is read from a socket, but an application should check for remaining data upon receipt ofFD_CLOSE
to avoid any possibility of losing data.Be aware that the application will only receive an
FD_CLOSE
message to indicate closure of a virtual circuit, and only when all the received data has been read if this is a graceful close. It will not receive anFD_READ
message to indicate this condition....
Here is a summary of events and conditions for each asynchronous notification message.
...
FD_CLOSE
: Only valid on connection-oriented sockets (for example, SOCK_STREAM)
When
WSAAsyncSelect()
called, if socket connection has been closed.After remote system initiated graceful close, when no data currently available to receive (Be aware that, if data has been received and is waiting to be read when the remote system initiates a graceful close, the
FD_CLOSE
is not delivered until all pending data has been read).After local system initiates graceful close with
shutdown()
and remote system has responded with "End of Data" notification (for example, TCP FIN), when no data currently available to receive.When remote system terminates connection (for example, sent TCP RST), and
lParam
will containWSAECONNRESET
error value.Note
FD_CLOSE
is not posted afterclosesocket()
is called.
Pulling out the network cable does not satisfy any of those conditions. This is actually by design, as networks are designed to handle unexpected outages so they can maintain existing connections as best as they can during short outages. Wait a few minutes until the OS times out and see what happens. Also, when you put the cable back in, the OS will validate pre-existing connections and then may or may not reset them at that time.
Upvotes: 1