Boost C++ Libraries: Ticket #6661: Different behavior on WIN and Linux https://svn.boost.org/trac10/ticket/6661 <p> Hi, I've found a different behavior at use of some functions with UDP protocol. </p> <p> Look at this code </p> <pre class="wiki"> io_service ios; udp::endpoint to(address::from_string("127.0.0.1"), port); udp::socket sender(ios, udp::v4()); udp::socket receiver(ios, udp::endpoint(udp::v4(), port)); const char buf[] = "Some test data..."; const size_t buf_len = sizeof(buf); char read_buf[buf_len]; char half_read_buf[buf_len / 2]; sender.send_to(buffer(buf, buf_len), to); try { udp::endpoint sender_point; receiver.receive_from(buffer(half_read_buf, sizeof(half_read_buf)), sender_point); } catch(exception&amp; ex) { string str = ex.what(); cerr &lt;&lt; "Exception: "&lt;&lt; ex.what() &lt;&lt; endl; } cout &lt;&lt; string(half_read_buf, sizeof(half_read_buf)) &lt;&lt; endl; sender.send_to(buffer(buf, buf_len), to); sender.send_to(buffer(buf, buf_len), to); cout &lt;&lt; "Available: " &lt;&lt; receiver.available() &lt;&lt; endl; receiver.receive(buffer(read_buf, sizeof(read_buf))); cout &lt;&lt; "Available: " &lt;&lt; receiver.available() &lt;&lt; endl; receiver.receive(buffer(read_buf, sizeof(read_buf))); cout &lt;&lt; "Available: " &lt;&lt; receiver.available() &lt;&lt; endl; </pre><p> Here we are reading half an datagramm and use socket::available() to look how much data into the socket. Execute this code on WIN32 and you get this output </p> <pre class="wiki">Exception: receive_from: The message was too large for the specified buffer and (for unreliable protocols only) any trailing portion of the message that did not fit into the buffer has been discarded. Some test Available: 36 Available: 18 Available: 0 </pre><p> Execute it on Linux and you get </p> <pre class="wiki">Some test Available: 18 Available: 18 Available: 0 </pre><p> It looks strange.<br /> Look into source </p> <pre class="wiki">boost/asio/detail/impl/socket_ops.ipp ------------------------------------- int recvfrom(socket_type s, buf* bufs, size_t count, int flags, socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code&amp; ec) { ... #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, &amp;bytes_transferred, &amp;recv_flags, addr, &amp;tmp_addrlen, 0, 0), ec); *addrlen = (std::size_t)tmp_addrlen; ... if (result != 0) return socket_error_retval; ec = boost::system::error_code(); return bytes_transferred; #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__) msghdr msg = msghdr(); init_msghdr_msg_name(msg.msg_name, addr); msg.msg_namelen = *addrlen; msg.msg_iov = bufs; msg.msg_iovlen = count; int result = error_wrapper(::recvmsg(s, &amp;msg, flags), ec); *addrlen = msg.msg_namelen; if (result &gt;= 0) ec = boost::system::error_code(); return result; } </pre><p> For WIN32 uses functions family WSARecv(<a class="ext-link" href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms741686(v=vs.85).aspx"><span class="icon">​</span>http://msdn.microsoft.com/en-us/library/windows/desktop/ms741686(v=vs.85).aspx</a>) they return status of error. And one of which is </p> <pre class="wiki">WSAEMSGSIZE The message was too large for the specified buffer and (for unreliable protocols only) any trailing portion of the message that did not fit into the buffer has been discarded. </pre><p> For Linux uses functions family recv (<a class="ext-link" href="http://linux.die.net/man/2/recv"><span class="icon">​</span>http://linux.die.net/man/2/recv</a>). They return the length of the message on successful completion or -1 and set status in errno if was error. But for them no the error if buffer length less that a received datagram.<br /> </p> <p> But if we uses function recvfrom, it sets this error into struct msghdr in the msg_flags </p> <pre class="wiki">MSG_TRUNC indicates that the trailing portion of a datagram was discarded because the datagram was larger than the buffer supplied. </pre><p> And also about function basic_datagram_socket::available. For WIN32 it returns length of all datagrams in the socket BUT for linux in returns length a one datagramm. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6661 Trac 1.4.3