<?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=43245&amp;view=findpost&amp;p=511480</guid>
        <pubDate>Sun, 14 Nov 2004 19:44:21 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=511480</link>
        <description><![CDATA[Nikolai: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <span class='tag-quote__quote-info'>ViGOur &#064; 28.05.04, 10:37</span><div class='quote '>И что на разныйх платформах у данного кода будут разные результаты?<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">LPTSTR &nbsp;lpBuffer=NULL;</div><div class="code_line">lpBuffer+4=lpData;</div><div class="code_line">CopyMemory( lpBuffer, reinterpret_cast&#60;char*&#62;(&amp;dwBytesToWrite), sizeof(DWORD));</div><div class="code_line">Клиент отправляет данные...</div><div class="code_line">&nbsp;</div><div class="code_line">Сервер получил данные...</div><div class="code_line">DWORD dwMsgSize=0;</div><div class="code_line">CopyMemory( reinterpret_cast&#60;char*&#62;(&amp;dwMsgSize), lpBuffer, sizeof(DWORD));</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
А если у тебя отправляется толко 100 символов, тогда можно было и 1 байт  ;) <br>
Но для реального отправления мне кажется ве-таки лучше использовать первые 4 байта, <br>
я думаю ты сам понимаешь почему...</div></div><br>
#include &lt;sys/types.h&gt;<br>
#include &lt;netinet/in.h&gt; /* if i remember right (on linux)*/<br>
<br>
/* on send part of system */<br>
... put_length_into_packet(u_int16_t length)<br>
   length = htons(length);/ * convert host order to network order */<br>
   memcpy(buffer, &amp;length, sizeof(length)); /* put 2 bytes into start of the packet */<br>
  ... /* prepare rest of rthe buffer */  <br>
 send(fd, buffer, sizeof(buffer), 0); <br>
<br>
/* on receive part of system */<br>
... get_packet(...)<br>
 u_int16_t length;<br>
 recv(fd, &amp;length, sizeof(length), MSG_PEEK);<br>
 length = ntohs(length);<br>
 recv(fd, buffer, length, MSG_WAITALL);<br>
<br>
For simplisity sake i omit check of recv and send return values]]></description>
        <author>Nikolai</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=495668</guid>
        <pubDate>Fri, 29 Oct 2004 07:27:07 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=495668</link>
        <description><![CDATA[Leprecon: <div class="tag-mod"><div class="tag-mod__prefix">M</div><div class="tag-mod__body"><strong class='tag-b'>Peter</strong>, раздел ФАКа предназначен только для статей и вопросов связанных с ними. Твой вопрос я отделил в тему&#58; <a class='tag-url' href='http&#58;//forum.sources.ru/index.php?showtopic=70783' target='_blank'>Куча ошибок в файле sys/socket</a></div></div>]]></description>
        <author>Leprecon</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=392663</guid>
        <pubDate>Thu, 01 Jul 2004 05:19:31 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=392663</link>
        <description><![CDATA[AQL: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
я думаю ты сам понимаешь почему...<br>
</div></div><br>
<br>
это всего лишь иллюстрация, как пользоваться приведёнными функциями, кто как хочет, так и использует.]]></description>
        <author>AQL</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=392592</guid>
        <pubDate>Thu, 01 Jul 2004 00:00:21 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=392592</link>
        <description><![CDATA[DrUnkard: 2Uncle_Bob<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Дело в этом:<br>
</div></div><br>
Эти пременные у него не изображены внутри какой-либо функции. Мож они глобальные? :blink: <br>
Тогда всё чики-пики. :rolleyes:]]></description>
        <author>DrUnkard</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367715</guid>
        <pubDate>Fri, 28 May 2004 08:15:57 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367715</link>
        <description><![CDATA[AQL: Такой я ещё не пробовал, .. но вроде бы тоже не должно работать.<br>Дело в том, что младший и старший байты на разных платформах перепутаны.<br>Ты отправил клиенту первым символом - младший байт, а он решил - что это старший, .... ну и т.д.]]></description>
        <author>AQL</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367713</guid>
        <pubDate>Fri, 28 May 2004 08:14:46 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367713</link>
        <description><![CDATA[UncleBob: Дело в этом:<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">TCHAR szLength[4]; // в szLength - мусор</div><div class="code_line">int nLength; &nbsp; &nbsp; &nbsp; // в nLength - тоже</div><div class="code_line">&nbsp;</div><div class="code_line">if(RecvNBytes(nSocket, szLength, 2) != 0) &nbsp;//приняли первые 2 байта - длину</div><div class="code_line">// но в других 2-х байтах все равно мусор!</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;return FALSE;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">nLength = atoi(szLength); &nbsp;//преобразовали 2 байта в длину</div><div class="code_line">// не 2, а непонятно сколько. первые два байта по делу, в остальных - неизвестно что, </div><div class="code_line">// а ведь еще это безобразие должно еще и нулем кончаться!</div></ol></div></div></div></div>]]></description>
        <author>UncleBob</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367685</guid>
        <pubDate>Fri, 28 May 2004 07:37:10 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367685</link>
        <description><![CDATA[ViGOur: И что на разныйх платформах у данного кода будут разные результаты?<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">LPTSTR &nbsp;lpBuffer=NULL;</div><div class="code_line">lpBuffer+4=lpData;</div><div class="code_line">CopyMemory( lpBuffer, reinterpret_cast&#60;char*&#62;(&amp;dwBytesToWrite), sizeof(DWORD));</div><div class="code_line">Клиент отправляет данные...</div><div class="code_line">&nbsp;</div><div class="code_line">Сервер получил данные...</div><div class="code_line">DWORD dwMsgSize=0;</div><div class="code_line">CopyMemory( reinterpret_cast&#60;char*&#62;(&amp;dwMsgSize), lpBuffer, sizeof(DWORD));</div></ol></div></div></div></div><br>
А если у тебя отправляется толко 100 символов, тогда можно было и 1 байт  ;) <br>
Но для реального отправления мне кажется ве-таки лучше использовать первые 4 байта, <br>
я думаю ты сам понимаешь почему...]]></description>
        <author>ViGOur</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367552</guid>
        <pubDate>Fri, 28 May 2004 05:22:13 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367552</link>
        <description><![CDATA[AQL: Сколька хочешь, дарагой, хоть 20&#33;  ;) . В примере макс. длина мессаги - 100 символов.<br>На самом деле там лучше использовать не atoi(szLength), а strtol с базисом 16, или ещё лучше - посылать (без преобразования в строку) байты числа nLength, здесь это НЕ сделано для наглядности, к тому же - со строкой понятно как работать на разных платформах, а вот, предположим, сборка из 4 -х байтов int на Apple и Intel проходит по разному  ;) .]]></description>
        <author>AQL</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367191</guid>
        <pubDate>Thu, 27 May 2004 14:40:09 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=367191</link>
        <description><![CDATA[ViGOur: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>if(RecvNBytes(nSocket, szLength, 2) &#33;= 0)  //приняли первые 2 байта - длину<br>
{<br>
  return FALSE;<br>
}</div></div><br>
Почему 2 байта, а не 4&#33;?  :)]]></description>
        <author>ViGOur</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=329407</guid>
        <pubDate>Thu, 01 Apr 2004 12:31:17 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=329407</link>
        <description><![CDATA[Dmitry: А можно и WSASelectEvent, это вроде даж лучше будет, но вот это для винды, о других ОС сказать не могу.]]></description>
        <author>Dmitry</author>
        <category>C/C++ FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=283181</guid>
        <pubDate>Sun, 18 Jan 2004 11:13:21 +0000</pubDate>
        <title>Считывание данных из сокета.</title>
        <link>https://forum.sources.ru/index.php?showtopic=43245&amp;view=findpost&amp;p=283181</link>
        <description><![CDATA[Aquila (AQL): Те, кто работал с tcp-ip сокетами, знают про всякие подводные камни, связаные с этим.<br>
Приведу несколько из них.<br>
<br>
Первый: данные в tcp-ip стеке могут появляться не все сразу, а кусками. Если клиент послал<br>
нам данные с помощью одной функции send(), это совсем не значит, что они могут быть приняты одной <br>
функцией recv().<br>
Второй: если с отправителем данных что либо случилось, и он не смог данные полностью, то возможны зависоны на функции recv() (при использовании блокирующих сокетов).Аналогично для фукнции send().<br>
<br>
<br>
Вашему вниманию представлены функции SendNBytes() и RecvNBytes(), которые избавлены от данных недостатков: используется функция select() для установки величины таймаута на однократный прием данных, и используется тот факт, что функция recv() в случае удачного приема возвращает количество байт, которые были реально приняты. <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">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">#define &nbsp; &nbsp; _SOCKET_TIMEOUT &nbsp; &nbsp;5000000 &nbsp; &nbsp; //величина таймаута в микросекундах</div><div class="code_line">&nbsp;</div><div class="code_line">int SendNBytes(int nSocket, char *pBuffer, int iMessageLength)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;int &nbsp; &nbsp; iRC &nbsp; &nbsp; &nbsp; &nbsp; = 0;</div><div class="code_line">&nbsp;&nbsp;int &nbsp; &nbsp; iSendStatus = 0;</div><div class="code_line">&nbsp;&nbsp;timeval SendTimeout;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;//установка величины таймаута</div><div class="code_line">&nbsp;&nbsp;SendTimeout.tv_sec &nbsp;= 0;</div><div class="code_line">&nbsp;&nbsp;SendTimeout.tv_usec = _SOCKET_TIMEOUT; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;fd_set fds;</div><div class="code_line">&nbsp;&nbsp;FD_ZERO(&amp;fds);</div><div class="code_line">&nbsp;&nbsp;FD_SET(nSocket, &amp;fds);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;//..до тех пор, пока нам нужно посылать данные...</div><div class="code_line">&nbsp;&nbsp;while(iMessageLength &#62; 0)</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;iRC = select(0, NULL, &amp;fds, NULL, &amp;SendTimeout);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//истек таймаут, возврат ошибки</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(!iRC)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return -1;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//произошла ошибка</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(iRC &#60; 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return WSAGetLastError();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//отправить несколько байт</div><div class="code_line">&nbsp;&nbsp; &nbsp;iSendStatus = send(nSocket, pBuffer, iMessageLength, 0); &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div><div class="code_line">&nbsp;&nbsp; &nbsp;//произошла ошибка в момент отправки данных</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(iSendStatus &#60; 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return WSAGetLastError();</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;//обновить буфер и счетчик</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;iMessageLength -= iSendStatus;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pBuffer += iSendStatus;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><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;</div><div class="code_line">&nbsp;</div><div class="code_line">//функция приема данных</div><div class="code_line">int ReceiveNBytes(int nSocket, char *pBuffer, int iStillToReceive)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;int &nbsp; &nbsp; iRC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = 0;</div><div class="code_line">&nbsp;&nbsp;int &nbsp; &nbsp; iReceiveStatus &nbsp; &nbsp;= 0;</div><div class="code_line">&nbsp;&nbsp;timeval ReceiveTimeout;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;//установка величины таймаута</div><div class="code_line">&nbsp;&nbsp;fd_set fds;</div><div class="code_line">&nbsp;&nbsp;FD_ZERO(&amp;fds);</div><div class="code_line">&nbsp;&nbsp;FD_SET(nSocket, &amp;fds);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;ReceiveTimeout.tv_sec &nbsp;= 0;</div><div class="code_line">&nbsp;&nbsp;ReceiveTimeout.tv_usec = _SOCKET_TIMEOUT; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 500 ms</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;//..пока данные не посланы..</div><div class="code_line">&nbsp;&nbsp;while(iStillToReceive &#62; 0)</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;iRC = select(0, &amp;fds, NULL, NULL, &amp;ReceiveTimeout);</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//выход по таймауту</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(!iRC)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return -1;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//произошла какая то ошибка</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(iRC &#60; 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return WSAGetLastError();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//прием нескольких байт</div><div class="code_line">&nbsp;&nbsp; &nbsp;iReceiveStatus = recv(nSocket, pBuffer, iStillToReceive, 0);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;//произошла ошибка в момент функции recv()</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(iReceiveStatus &#60; 0)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return WSAGetLastError();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;//изменили величину счетчика и буфер</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;iStillToReceive -= iReceiveStatus;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;pBuffer += iReceiveStatus;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
как пользоваться:<br>
<br>
Хорошим тоном считается посылка в начале основного сообщения информацию о длине сообщения.<br>
Нужно договориться (разработчикам клиента и сервера), что, например, первые 2 или 4 байта в начале<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;</div><div class="code_line">&nbsp;</div><div class="code_line">TCHAR &nbsp; *szMessage;</div><div class="code_line">TCHAR &nbsp; szLength[4];</div><div class="code_line">int nLength;</div><div class="code_line">&nbsp;</div><div class="code_line">if(RecvNBytes(nSocket, szLength, 2) != 0) &nbsp; //приняли первые 2 байта - длину</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;return FALSE;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">nLength = atoi(szLength); &nbsp; &nbsp; &nbsp; //преобразовали 2 байта в длину</div><div class="code_line">szMessage = new TCHAR[szLength];</div><div class="code_line">&nbsp;</div><div class="code_line">if(RecvNBytes(nSocket, szMessage, nLength) !=0) //приняли полное сообщение</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;return FALSE;</div><div class="code_line">}</div></ol></div></div></div></div>]]></description>
        <author>Aquila (AQL)</author>
        <category>C/C++ FAQ</category>
      </item>
	
      </channel>
      </rss>
	