- 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;
}
1) В строках 55-56 бесполезная проверка, уже проделанная выше в строках 11-12, pSocket с тех пор измениться не должен.
2) sizeof( chBuf ) / sizeof( *chBuf ) в строке 35. recv в третьем параметре принимает число байт, а не символов, поэтому следует использовать просто sizeof(chBuf).
3) В строке 33 мутноватое условие, не соответствующее комментарию в 48й.
4) Сомнительна необходимость WSASetLastError(WSAETIMEDOUT) в 45й строке.
5) Стоило бы вернуть сокет в блокирующий режим перед вызовом closesocket или же отключить SO_LINGER:
Enabling the SO_LINGER socket option with a nonzero time-out interval on a socket with its non-blocking mode enabled is not recommended. In this case, the call to the closesocket function will fail, and the WSAGetLastError function will return WSAEWOULDBLOCK if the close operation cannot be completed immediately. However the socket handle is still valid, and a disconnect is not initiated. Your program must call the closesocket function again to close the socket.
Если же вы считаете, что сама логика закрыть выходной канал, дочитать все что придет, закрыть сокет не имеет права на жизнь - вы ошибаетесь:
http://docstore.mik.ua/apache/manual/misc/fin_wait_2.html
The solution in all cases is to send the response, close only the write half of the connection (what shutdown is supposed to do), and continue reading on the socket until it is either closed by the client (signifying it has finally read the response) or a timeout occurs.
Мне кажется или большинство любителей разнообразных языков - работают сишниками++ или пуританскими сишниками? В этом есть какаято закономерность.
Есть. Те кто начал с уютненьких языков (вроде C#) за всю свою карьеру могут ни разу и не задуматься о том, что существуют и другие языки с другими концепциями. А начавший с Си невольно заинтересуется и другими языками...
Истинно. Они дальше вендоплатформы и VB никуда не смотрят.
Но есть же Mono
A там есть Parallel LINQ?
Кстати не удержался - LINQ-рейтрейсинг.
http://tirania.org/blog/archive/2008/Jul-26-1.html
1)2)3) ... N-1)N)
Ну и автор не привел свое мнение, что же именно он считает говнокодом. Было бы интересно его услышать.
Всегда Ваш, обобреный бобёр.
В свое время словил багофичу с алгоритмом Nagle. По глупости не буферизовывал пакет целиком, а отправлял первым write'ом длину, потом вторым write'ом контент, а затем ждал ответа. Как оно лагало... По реакции терминала казалось что он подключен через GPRS а не по локалке...
Вот статейка про данную проблему, если кому интересно:
http://www.stuartcheshire.org/papers/NagleDelayedAck/
- ко ко ко. Петусишник наваял. ко ко ко
Govno:
- Таки зря вы это запостили на говнокод. Я тоже govno не вижу. А я своих за версту чую. Даже комментарии есть. Названия некоторых переменных только смущают и функция длинновата, но не более.
"Любой код, длиннее 50 строк - говно"
Особенно если это одна функция...
P.S. И вообще "любой код - говно"
Чем полезней код/язык, тем больше в нем говна.
Вывод: только СОВЕРШЕННО бесполезный код/язык не содержат говна.
Я не знаю, как именно сказал С. Макконелл, но имхо я не ошибся, поправив.
Это в "Совершенном коде"?
Предвижу поедающих меня олдфагов со словами "Ха-ха-ха ньюфажина, Макконелла не читал!"
cheers
>ко ко ко.
Это да.
Но вот был тут некий usrus, тоже коды на Си выкладывал.