<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749792</guid>
        <pubDate>Thu, 11 Nov 2010 10:19:45 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749792</link>
        <description><![CDATA[hash_2000: ну ладно ... мне мой способ нравится .. потом какнибудь попробую его еще под нагрузкой протестировать <br>и вообще тему закрывается тут целая куча способов &#33; пусть каждый по себе выбирает &#33;&#33;  :D<br>Всем участвовавшим спасибо &#33;&#33;&#33;]]></description>
        <author>hash_2000</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749689</guid>
        <pubDate>Thu, 11 Nov 2010 08:50:17 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749689</link>
        <description><![CDATA[popsa: :) помойму ужасно<br>
Быстренько тебе набросал, как в моем представлении все это должно выглядеть, работает - не работает уж не знаю, отладчиком походишь отладишь<br>
зы это даже компилиться на солярисе :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">typedef std::vector&#60;int&#62; CSocketList;</div><div class="code_line">&nbsp;&nbsp; &nbsp;CSocketList socket_list;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int sv_sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( sv_sock == -1 ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return(EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int sock_value = 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( setsockopt( sv_sock, SOL_SOCKET, SO_REUSEADDR,(char*)&amp;sock_value, sizeof(sock_value)) != 0) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return(EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( setsockopt( sv_sock, IPPROTO_TCP, TCP_NODELAY,(char*)&amp;sock_value, sizeof(sock_value)) != 0) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return(EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;sockaddr_in svaddr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_family = AF_INET;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_port = htons(15555);</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_addr.s_addr = INADDR_ANY;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( bind( sv_sock, (sockaddr *)&amp;svaddr, sizeof(svaddr) ) != 0) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return(EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( listen( sv_sock, FD_SETSIZE ) != 0 ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return(EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;socket_list.push_back(sv_sock);</div><div class="code_line">&nbsp;&nbsp; &nbsp;bool working = true;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while(working) {</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fd_set fdr, fde, fdw;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FD_ZERO(&amp;fdr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FD_ZERO(&amp;fdw);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FD_ZERO(&amp;fde);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;const size_t socket_list_size = socket_list.size();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for(size_t i = 0; i &#60; socket_list_size; ++i) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_SET(socket_list[i], &amp;fdr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_SET(socket_list[i], &amp;fdw);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_SET(socket_list[i], &amp;fde);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;int r = select(0, &amp;fdr, &amp;fdw, &amp;fde, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if(r &#62; 0) {</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for(size_t i = 0; i &#60; socket_list_size; ++i) {</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int isListener;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int dmSize = sizeof (isListener);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(getsockopt(socket_list[i], SOL_SOCKET, SO_ACCEPTCONN, (char*) &amp; isListener, &amp;dmSize) != 0) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return (EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(FD_ISSET(socket_list[i], &amp;fdw)) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(FD_ISSET(socket_list[i], &amp;fdr)) {</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(!isListener)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //if recv failed - disconnected</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int new_sd = accept(socket_list[i], 0, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(new_sd &#62; 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;socket_list.push_back(new_sd);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(FD_ISSET(socket_list[i], &amp;fde)) {</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(isListener)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return(EXIT_FAILURE);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;close(socket_list[i]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;socket_list[i] = -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for(int i = socket_list_size - 1; i &#62; 0; i--) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(socket_list[i] == -1)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;socket_list.erase(socket_list.begin() + i);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
а не, ошибся с fdw, когда кто то присоединяеться срабатывает fdr и судя по докам из msdn <br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
In summary, a socket will be identified in a particular set when select returns if:<br>
<br>
readfds:<br>
If listen has been called and a connection is pending, accept will succeed.<br>
Data is available for reading (includes OOB data if SO_OOBINLINE is enabled).<br>
Connection has been closed/reset/terminated.<br>
<br>
writefds:<br>
If processing a connect call (nonblocking), connection has succeeded.<br>
Data can be sent.<br>
<br>
exceptfds:<br>
If processing a connect call (nonblocking), connection attempt failed.<br>
OOB data is available for reading (only if SO_OOBINLINE is disabled).<br>
</div></div><br>
<br>
по fde нельзя отвал определить. В общем сиди ковыряйся, потом расскажешь  :D о результатах.]]></description>
        <author>popsa</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749605</guid>
        <pubDate>Thu, 11 Nov 2010 07:14:43 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749605</link>
        <description><![CDATA[hash_2000: ну вот пожалуйста ... примерно так , проверяем ващ способ :<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// это все сервер</div><div class="code_line">&nbsp;</div><div class="code_line">#include &#60;winsock2.h&#62;</div><div class="code_line">#pragma comment(lib, &quot;wsock32.lib&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">SOCKET sv_sock = INVALID_SOCKET;</div><div class="code_line">fd_set fd_buf;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">void Close( BOOL bForce = FALSE )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( ( sv_sock == INVALID_SOCKET || sv_sock == SOCKET_ERROR ) || </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;bForce ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;closesocket ( sv_sock );</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">int _tmain(int argc, _TCHAR* argv[])</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSADATA w_data;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSAStartup( MAKEWORD( 2, 0 ), &amp;w_data );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;sv_sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( sv_sock == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int sock_value = 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( setsockopt( sv_sock, SOL_SOCKET, SO_REUSEADDR,(char*)&amp;sock_value, sizeof(sock_value)) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( setsockopt( sv_sock, IPPROTO_TCP, TCP_NODELAY,(char*)&amp;sock_value, sizeof(sock_value)) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( ioctlsocket( sv_sock, FIONBIO, (u_long *) &amp;sock_value ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;sockaddr_in svaddr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_family = AF_INET;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_port = htons(15555);</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_addr.s_addr = ADDR_ANY;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( bind( sv_sock, (LPSOCKADDR)&amp;svaddr, sizeof(SOCKADDR) ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( listen( sv_sock, FD_SETSIZE ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FD_ZERO( &amp;fd_buf );</div><div class="code_line">&nbsp;&nbsp; &nbsp;FD_SET( sv_sock, &amp;fd_buf );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;char radbuf[ 16 * 1024 ];</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while( 1 )</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fd_set waitSet, exctSet;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memcpy( &amp;waitSet, &amp;fd_buf, sizeof(fd_set) );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memcpy( &amp;exctSet, &amp;fd_buf, sizeof(fd_set) );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;int ret = select( 0, &amp;waitSet, 0, &amp;exctSet, 0 );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( ret &#60;= 0 )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for( u_int fd = 0 ; fd &#60; waitSet.fd_count ; fd ++ )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SOCKET sc = waitSet.fd_array[ fd ];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int isListener;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int dmSize = sizeof(isListener);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( getsockopt( sc, SOL_SOCKET, SO_ACCEPTCONN,(char*) &amp;isListener, &amp;dmSize) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( isListener )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ктото зацепился </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int clAddrLen = sizeof(sockaddr_in);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sockaddr_in cl_addr;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SOCKET cl = accept( sc, (LPSOCKADDR)&amp;cl_addr, &amp;clAddrLen );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( cl == INVALID_SOCKET )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_SET( cl, &amp;fd_buf );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ктото из клиентов передает данные</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// или отвалился </div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// анука проверимка !!!</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( FD_ISSET( sc, &amp;exctSet ) )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_CLR( sc, &amp;fd_buf );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;closesocket( sc );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int read_size = recv ( sc, radbuf, 16 * 1024, 0 );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Close( TRUE );</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSACleanup();</div><div class="code_line">&nbsp;&nbsp; &nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// а все это клиент </div><div class="code_line">&nbsp;</div><div class="code_line">#include &#60;winsock2.h&#62;</div><div class="code_line">#pragma comment(lib, &quot;wsock32.lib&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">SOCKET cl_sock = INVALID_SOCKET;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">void Close( BOOL bForce = TRUE )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( ( cl_sock == INVALID_SOCKET || cl_sock == SOCKET_ERROR ) || </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;bForce ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;closesocket ( cl_sock );</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">int _tmain(int argc, _TCHAR* argv[])</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSADATA w_data;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSAStartup( MAKEWORD( 2, 0 ), &amp;w_data );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cl_sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( cl_sock == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;sockaddr_in svaddr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_family = AF_INET;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_port = htons(15555);</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_addr.s_addr = inet_addr( &quot;127.0.0.1&quot; );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( connect(cl_sock,(LPSOCKADDR)&amp;svaddr,sizeof(SOCKADDR)) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Close( TRUE );</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSACleanup();</div><div class="code_line">&nbsp;&nbsp; &nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
начинаем трассировать &#33;&#33;&#33; <br>
когда проходит connect на сервере select возвращает управление , ну и собственно добавляет полученное соединение <br>
но зато когда проходим через closesocket на клиенте ... select опять возвращает управление но exctSet.fd_count = 0 поэтому и FD_ISSET( sc, &amp;exctSet ) вернет ложь &#33;&#33;&#33;<br>
<br>
<br>
а вот исправленная версия сервера<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#include &#60;winsock2.h&#62;</div><div class="code_line">#pragma comment(lib, &quot;wsock32.lib&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">SOCKET sv_sock = INVALID_SOCKET;</div><div class="code_line">fd_set fd_buf;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">void Close( BOOL bForce = FALSE )</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( ( sv_sock == INVALID_SOCKET || sv_sock == SOCKET_ERROR ) || </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;bForce ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;closesocket ( sv_sock );</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">int _tmain(int argc, _TCHAR* argv[])</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSADATA w_data;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSAStartup( MAKEWORD( 2, 0 ), &amp;w_data );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;sv_sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( sv_sock == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int sock_value = 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( setsockopt( sv_sock, SOL_SOCKET, SO_REUSEADDR,(char*)&amp;sock_value, sizeof(sock_value)) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( setsockopt( sv_sock, IPPROTO_TCP, TCP_NODELAY,(char*)&amp;sock_value, sizeof(sock_value)) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( ioctlsocket( sv_sock, FIONBIO, (u_long *) &amp;sock_value ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;sockaddr_in svaddr;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_family = AF_INET;</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_port = htons(15555);</div><div class="code_line">&nbsp;&nbsp; &nbsp;svaddr.sin_addr.s_addr = ADDR_ANY;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( bind( sv_sock, (LPSOCKADDR)&amp;svaddr, sizeof(SOCKADDR) ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ( listen( sv_sock, FD_SETSIZE ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FD_ZERO( &amp;fd_buf );</div><div class="code_line">&nbsp;&nbsp; &nbsp;FD_SET( sv_sock, &amp;fd_buf );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;char radbuf[ 16 * 1024 ];</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while( 1 )</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fd_set waitSet;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;memcpy( &amp;waitSet, &amp;fd_buf, sizeof(fd_set) );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;int ret = select( 0, &amp;waitSet, 0, 0, 0 );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( ret &#60;= 0 )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for( u_int fd = 0 ; fd &#60; waitSet.fd_count ; fd ++ )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SOCKET sc = waitSet.fd_array[ fd ];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int isListener;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int dmSize = sizeof(isListener);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( getsockopt( sc, SOL_SOCKET, SO_ACCEPTCONN,(char*) &amp;isListener, &amp;dmSize) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( isListener )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ктото зацепился </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int clAddrLen = sizeof(sockaddr_in);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sockaddr_in cl_addr;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SOCKET cl = accept( sc, (LPSOCKADDR)&amp;cl_addr, &amp;clAddrLen );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( cl == INVALID_SOCKET )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_SET( cl, &amp;fd_buf );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ктото из клиентов передает данные</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// или отвалился </div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// зато вот тут вроде как все работает !!!</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;u_long read_data_size;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( ioctlsocket(sc, FIONREAD, &amp;read_data_size ) == SOCKET_ERROR ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Close(); </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( read_data_size == 0 ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FD_CLR( sc, &amp;fd_buf );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;closesocket( sc );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int read_size = recv ( sc, radbuf, 16 * 1024, 0 );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Close( TRUE );</div><div class="code_line">&nbsp;&nbsp; &nbsp;WSACleanup();</div><div class="code_line">&nbsp;&nbsp; &nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
тут вроде как и цикл не нужно проходить для проверки , я имею ввиду FD_ISSET .. ведь DS_SETSIZE можно сделать и больше 64 .. просто возвращает размер данных в буфере сокета и все .. <br>
или всетаки тут есть какойто серьезный баг]]></description>
        <author>hash_2000</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749577</guid>
        <pubDate>Thu, 11 Nov 2010 06:25:02 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749577</link>
        <description><![CDATA[popsa: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>чтото не работает ни один ни другой способ ... ни с использованием exceptfds в select&#39;е</div></div><br>
показывай полный код ;) . У всех работает у вас нет, что то неправильно значит<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>ни getsockopt + SO_ERROR</div></div><br>
 :) про это я тоже писал, что в винде не получилось при обрыве получить ошибку таким способом<br>
<br>
 :) и вабще я немного логику не понимаю, если в селект переадються все fd, то ведь однозначно можно определить, почему селект вернул управление. В общем давай полный код.]]></description>
        <author>popsa</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749561</guid>
        <pubDate>Thu, 11 Nov 2010 05:53:30 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749561</link>
        <description><![CDATA[hash_2000: чтото не работает ни один ни другой способ ... ни с использованием exceptfds в select&#39;е <br>
ни getsockopt + SO_ERROR ... я их кстати пробовал уже и при разрыве соединения в exceptfds всегда оставался пустым и соответственно <br>
способ - if (FD_ISSET(gw_socket, &amp;fde)) не прокатил бы ... может при создании сокета какието опции нужно выставить ? <br>
я нашел другой способ ... но только для проверки сокетов которые ожидают данные:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;&nbsp; &nbsp;// после того как select вернул управление</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int isListen;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// проверяем не слушающий ли сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp;getsockopt( cl_socket, SOL_SOCKET, SO_ACCEPTCONN, (char*)&amp;isListen, sizeof(isListen);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( isListen == 0 )</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// проверяем состояние буфера чтения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;int nCountBytes;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ioctlsocket( cl_socket, FIONREAD, (u_long*)&amp;nCountBytes );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( nCountBytes == 0 )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// если попали сюда то сокет наверное отсоеденился </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// это всеравно что при выполнении recv будет возвращен 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
 <br>
<br>
сколько не смотрел тем на форумах или исходников уже рабочих программ в основном все проверяют состояние сокета ожидающего прием данных <br>
именно попыткой чтения из него ну и если recv возвращает 0 то значит клиент закрыл соединение.<br>
вот подскажите , опытные люди, корректен ли этот способ или тут есть какието подводные камни ?<br>
<br>
по мне так этот способ будет даже относительно шустрее работать чем предложенный if (FD_ISSET(gw_socket, &amp;fde)) ..]]></description>
        <author>hash_2000</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749159</guid>
        <pubDate>Wed, 10 Nov 2010 15:58:17 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749159</link>
        <description><![CDATA[Oleg2004: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=318020&view=findpost&p=2749141'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>popsa &#064; <time class="tag-quote__quoted-time" datetime="2010-11-10T15:46:53+00:00">10.11.10, 15:46</time></span><div class='quote '> По мне<br>
      if (FD_ISSET(gw_socket, &amp;fde))<br>
уже зватает чтобы закрывать соединение</div></div><br>
Логично.<br>
Т.е достаточно - но не необходимо. Теоретически может быть и иная причина помещения в набор....<br>
Но - как я уже выше согласился - в первом приближении это работает]]></description>
        <author>Oleg2004</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749141</guid>
        <pubDate>Wed, 10 Nov 2010 15:46:53 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749141</link>
        <description><![CDATA[popsa: ;) По мне <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">if (FD_ISSET(gw_socket, &amp;fde))</div></ol></div></div></div></div> уже зватает чтобы закрывать соединение<br>
А про винду + getsockopt + SO_ERROR, ничего толкового не скажу, но когда то переносил код из соляриса(там как раз по наличию ошибки(SO_ERROR) отвал делался), то в винде это уже не работало, ибо getsockopt возвращал в коде ошибки 0, даже когда на другой стороне уже закрыли соединение.]]></description>
        <author>popsa</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749064</guid>
        <pubDate>Wed, 10 Nov 2010 15:02:18 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749064</link>
        <description><![CDATA[Oleg2004: Идея распихать по нескольким наборам - она в принципе работает.<br>
//error - disconnect;  <br>
Но вот для определения ошибки на Error-сокете надо использовать getsockopt<br>
например:<br>
·	Ошибка сокета, ожидающая обработки. Операция записи в сокет не блокируется и возвратит ошибку (-1) со значением переменной <strong class='tag-b'>еrrnо</strong>, указывающей на конкретное условие ошибки. Эти ошибки, ожидающие обработки, можно также получить и сбросить, вызвав функцию getsockopt() с параметром сокета SO_ERROR.<br>
<br>
Но это для UNIX-систем. Там есть errno.<br>
Как для винды?????????]]></description>
        <author>Oleg2004</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749000</guid>
        <pubDate>Wed, 10 Nov 2010 14:20:36 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2749000</link>
        <description><![CDATA[popsa: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>FD_ISSET в любом случае вернет истину ... ведь сокет в массиве и так есть &#33;&#33;&#33;</div></div><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">int ret = select( &amp;pWait, 0,0,0 );</div></ol></div></div></div></div><br>
 :lool: при таком использовании селекта,  да.<br>
<br>
судя по куску кода, ты имеешь очень смутное представление о функции select и о том как с ней работать<br>
<br>
Вот маленький кусок кода из работающей программы<br>
и не забудь почитать хотя бы <a class='tag-url' href='http://msdn.microsoft.com/en-us/library/ms740141(v=VS.85).aspx' target='_blank'>описание</a> используемых тобой функций<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">while(connected)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; fd_set fdr, fde;</div><div class="code_line">&nbsp;&nbsp; &nbsp; FD_ZERO(&amp;fdr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; FD_ZERO(&amp;fde);</div><div class="code_line">&nbsp;&nbsp; &nbsp; FD_SET(gw_socket, &amp;fdr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; FD_SET(gw_socket, &amp;fde); &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; int res = select(gw_socket + 1, &amp;fdr, 0, &amp;fde, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; if (res &#62; 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (FD_ISSET(gw_socket, &amp;fdr))</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//recv &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (FD_ISSET(gw_socket, &amp;fde))</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //error - disconnect; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; }</div><div class="code_line">}</div></ol></div></div></div></div>]]></description>
        <author>popsa</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748928</guid>
        <pubDate>Wed, 10 Nov 2010 13:30:43 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748928</link>
        <description><![CDATA[hash_2000: к сожалению (как выясняется) пишу под windows&#33;<br>честно говоря не думал что настолько большая разница.. <br>но я вот думал что раз WSAAsyncSelect или WSAEventSelect умеют определять такие события то и без <br>их помощи можно это определить ведь они, как мне кажется, являются оболочкой на winsock&#39;овскими функциями типа select ...<br>программа уже написана без использования WSA а тут такой глюк вылез ... а чтобы на асинхронные сокеты перейти много переписывать &#33;&#33;]]></description>
        <author>hash_2000</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748903</guid>
        <pubDate>Wed, 10 Nov 2010 13:06:47 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748903</link>
        <description><![CDATA[Oleg2004: Какая ОС?<br>
Если Windows -  то функциональность select() недостаточна - и сетевое I/O не сможет эффективно обслуживаться.<br>
FD_ISSET - это и все, что можно сделать. <br>
Для Виндов надо использовать WSAAsyncSelect или WSAEventSelect<br>
Для Линуха - типа poll()<br>
2.5.10.	Функция poll()<br>
poll() является вариантом select(). Задается массив из nfds структур типа <br>
       <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;struct pollfd </div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int fd; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* описатель файла */</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;short events; &nbsp; &nbsp; /* запрошенные события */</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;short revents; &nbsp; &nbsp;/* возвращенные события */</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;};</div></ol></div></div></div></div><br>
и значения timeout в миллисекундах. Отрицательное значение указывает на бесконечный таймер. Поле fd содержит описатель открытого файла. Поле events - это входной параметр, указывающий на битовую маску событий, важных для приложения. Поле revents - это возвращаемый параметр, в который ядро помещает информацию о произошедших событиях, запрошенных или типа POLLERR, POLLHUP или POLLNVAL. (Эти три битовых флага не будут иметь смысла при использовании в поле events, поэтому будут установлены в поле revents, если соответствующее условие истинно). Если ни одно из запрошенных событий не случилось или не произошла ни одна из ошибок, то ядро ждет их появления до истечения срока таймера. Вот возможные биты, описанные в &lt;sys/poll.h&gt;: <br>
События ввода/вывода<br>
Событие	   	Флаг poll()  	Когда происходит<br>
Чтение		POLLIN	Пришли новые данные.<br>
Чтение		POLLIN	Установка соединения завершена (для сокетов, ориентированных на соединения)<br>
Чтение		POLLHUP	Другая сторона инициировала запрос на разъединение.<br>
Чтение		POLLHUP	Соединение разорвано (только для протоколов, ориентированных на соединение). Если производится запись в сокет, то также посылается сигнал SIGPIPE.<br>
Запись		POLLOUT	Сокет имеет достаточно места в буфере передачи для записи в него новых данных.<br>
Чтение/запись	POLLIN|POLLOUT	Исходящий connect() завершен.<br>
Чтение/запись	POLLERR	Произошла асинхронная ошибка.<br>
Чтение/запись	POLLHUP	Другая сторона закрыла (shutdown) одно направление.<br>
Исключение	POLLPRI	Пришли неотложные данные. При этом посылается сигнал SIGURG.<br>
<br>
Здесь точно можно найти сетевое событие, которое вызвало сигнал.....]]></description>
        <author>Oleg2004</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748802</guid>
        <pubDate>Wed, 10 Nov 2010 11:40:48 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748802</link>
        <description><![CDATA[hash_2000: FD_ISSET в любом случае вернет истину ... ведь сокет в массиве и так есть &#33;&#33;&#33; <br>
ну вот например так : (реальный код не могу выложить потому что он слишком громоздкий, много будет не по теме )<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">fd_set g__arr;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">void Init ()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;SOCKET sock = // ... создаем сокет в режиме listen на какойто порт</div><div class="code_line">&nbsp;&nbsp; &nbsp;FD_SET( sock, &amp;g__arr );</div><div class="code_line">&nbsp;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void Wait ()</div><div class="code_line">{</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; while( 1 )</div><div class="code_line">&nbsp;&nbsp; {</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;fd_set pWait;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;memcpy( &amp;pWait, &amp;g__arr, sizeof(fd_set) );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // вот тут ждем вечно </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;int ret = select( &amp;pWait, 0,0,0 );</div><div class="code_line">&nbsp;&nbsp; // как только чтото пришло </div><div class="code_line">&nbsp;&nbsp; // вот тут например и обрабатываем все что нам пришло на порты которые слушаются</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for( int i = 0 ; i &#60; pWait.fd_count ; i ++ )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // если это попытка соедениться то делаем :</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SOCKET cl = accept( m_buf.fd_array[i], ... );</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FD_SET( cl, &amp;g__arr );</div><div class="code_line">&nbsp;&nbsp; // если это был клиентский сокет на который должны были прийти какието данные ... </div><div class="code_line">&nbsp;&nbsp; // то читаем данные и обрабатывает </div><div class="code_line">&nbsp;&nbsp; // но если ктото из клиентских сокетов сделал closesocket то select вернет в pWait массив сокеты </div><div class="code_line">&nbsp;&nbsp; // которые сделали closesocket и ret будет равен количеству элементов в pWait &nbsp;.... </div><div class="code_line">&nbsp;&nbsp; // &nbsp; и вот как тут вот узнать что клиент именно разорвал соединение а не передает данные ????</div><div class="code_line">&nbsp;&nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">void main ()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; Init();</div><div class="code_line">&nbsp;&nbsp; &nbsp; Wait();</div><div class="code_line">&nbsp;</div><div class="code_line">}</div></ol></div></div></div></div>]]></description>
        <author>hash_2000</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748777</guid>
        <pubDate>Wed, 10 Nov 2010 11:16:08 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748777</link>
        <description><![CDATA[popsa: <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">if(FD_ISSET(sock, &amp;fde)){</div><div class="code_line">....</div><div class="code_line">}</div></ol></div></div></div></div><br>
а вообще в поиск по select + FD_ISSET]]></description>
        <author>popsa</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748708</guid>
        <pubDate>Wed, 10 Nov 2010 10:35:02 +0000</pubDate>
        <title>как определить что select вернул сокеты с дисконнектом</title>
        <link>https://forum.sources.ru/index.php?showtopic=318020&amp;view=findpost&amp;p=2748708</link>
        <description><![CDATA[hash_2000: Всем здравствуйте &#33;<br>такая вот проблемка .. есть сервер который принимает клиентские подключения и записывает их все в общую <br>fd_set ну и слушает когда поступит подключение или прием данных через, соответственно, select .. <br>так вот .. если ктото из клиентов сделал у себя closesocket то функция select так же как и приеме данных вернет буфер с откликнувшимися сокетами<br>... может кто знает ... вот как определить именно в том месте где select вернула управление что сокет не данные прислал а именно отключился,<br>без использования recv .. дело в том что чтение данных уже проводится в потоках, а хотелось бы определить отключенный сокет еще до того как он <br>отправился на обработку в поток ... есть ли вообще такая возможность?]]></description>
        <author>hash_2000</author>
        <category>C/C++: Сетевое программирование</category>
      </item>
	
      </channel>
      </rss>
	