Subject: [Boost-bugs] [Boost C++ Libraries] #6661: Different behavior on WIN and Linux
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-03-08 07:58:05
#6661: Different behavior on WIN and Linux
-------------------------------------+--------------------------------------
Reporter: cupper.jj@⦠| Owner: chris_kohlhoff
Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
Version: Boost 1.49.0 | Severity: Problem
Keywords: udp, available, receive |
-------------------------------------+--------------------------------------
Hi, I've found a different behavior at use of some functions with UDP
protocol.
Look at this code
{{{
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& ex)
{
string str = ex.what();
cerr << "Exception: "<< ex.what() << endl;
}
cout << string(half_read_buf, sizeof(half_read_buf)) << endl;
sender.send_to(buffer(buf, buf_len), to);
sender.send_to(buffer(buf, buf_len), to);
cout << "Available: " << receiver.available() << endl;
receiver.receive(buffer(read_buf, sizeof(read_buf)));
cout << "Available: " << receiver.available() << endl;
receiver.receive(buffer(read_buf, sizeof(read_buf)));
cout << "Available: " << receiver.available() << endl;
}}}
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
{{{
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
}}}
Execute it on Linux and you get
{{{
Some test
Available: 18
Available: 18
Available: 0
}}}
It looks strange.[[BR]]
Look into source
{{{
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& ec)
{
...
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
&bytes_transferred, &recv_flags, addr, &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, &msg, flags), ec);
*addrlen = msg.msg_namelen;
if (result >= 0)
ec = boost::system::error_code();
return result;
}
}}}
For WIN32 uses functions family WSARecv([http://msdn.microsoft.com/en-
us/library/windows/desktop/ms741686(v=vs.85).aspx]) they return status of
error. And one of which is
{{{
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.
}}}
For Linux uses functions family recv ([http://linux.die.net/man/2/recv]).
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]]
But if we uses function recvfrom, it sets this error into struct msghdr in
the msg_flags
{{{
MSG_TRUNC
indicates that the trailing portion of a datagram was discarded because
the datagram was larger than the buffer supplied.
}}}
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.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/6661> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:09 UTC