- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
int closeestsockptr( SOCKET* pSocket )
{
char chBuf[ 100 ];
fd_set rdevents, exevents;
struct timeval tv;
int iRetVal = 1;
int optlen;
SOCKET s = INVALID_SOCKET;
BOOL bLinger;
LINGER lng;
if( NULL == pSocket || INVALID_SOCKET == *pSocket )
return SOCKET_ERROR;
s = *pSocket;
optlen = sizeof( bLinger );
iRetVal = getsockopt( s, SOL_SOCKET, SO_DONTLINGER, ( char* )&bLinger, &optlen );
if( 0 == iRetVal && TRUE == bLinger ) //linger is off
{
lng.l_onoff = 1; //set linger on
lng.l_linger = 1; //set linger timeout to 1 second
iRetVal = setsockopt( s, SOL_SOCKET, SO_LINGER, ( char* )&lng, sizeof( lng ) );
if( 0 == iRetVal )
{
if( 0 == shutdown( s, SD_SEND ) )
{
tv.tv_sec = 3; //seconds
tv.tv_usec = 0; //microseconds
while( 1 )
{
FD_ZERO( &rdevents );
FD_ZERO( &exevents );
addsock2fd( &rdevents, NULL, &exevents, s ); //FD_SET( s, &rdevents ), FD_SET( s, &exevents );
iRetVal = select( 1, &rdevents, NULL, &exevents, &tv );
if( SOCKET_ERROR != iRetVal && 0 != iRetVal && FD_ISSET ( s, &rdevents ) && !FD_ISSET ( s, &exevents ) )
{
iRetVal = recv( s, chBuf, sizeof( chBuf ) / sizeof( *chBuf ), 0 );
if( iRetVal > 0 ) //Some data received
continue;
if( 0 == iRetVal ) //Receive FD_CLOSE
break;
else //SOCKET_ERROR returned
break;
}
else if( 0 == iRetVal ) //exceeded the timeout
{
WSASetLastError( WSAETIMEDOUT );
break;
}
else //SOCKET_ERROR returned
break;
}
}
}
}
if( NULL == pSocket || INVALID_SOCKET == *pSocket )
return SOCKET_ERROR;
iRetVal = closesocket( *pSocket );
*pSocket = INVALID_SOCKET;
return iRetVal;
}