I'm struggling with two errors with Boost.Asio.
The first occurs when I try to receive data on a socket:
char reply[1024];
boost::system::error_code error;
size_t reply_length = s.receive(boost::asio::buffer(reply, 1024), 0, error);
if (error) cout << error.message() << endl; //outputs "End of file"
The second occurs when I try to create an ip::tcp::socket from a (valid!) native socket:
boost::asio::io_service ioserv;
boost::asio::ip::tcp::socket s(ioserv);
boost::system::error_code error;
s.assign(boost::asio::ip::tcp::v4(), nativeSocket, error);
if (error) cout << error.message() << endl; //outputs "The parameter is incorrect"
With all these troubles an no documentation to turn to, I am tempted to go back to BSD sockets, but I'm having my own problems there...so if anyone can help, I'd really appreciate it.
EDIT: Regarding number 2, nativeSocket is declared thusly:
SOCKET nativeSocket = INVALID_SOCKET;
nativeSocket = accept(svr_sock, (struct sockaddr*)&sin, &size);
After that, a few other things are done to the socket -- namely, setting it as non-blocking using ioctlsocket, and using setsockopt for SO_LINGER and SO_OOBINLINE.
This is not a complete solution to your second problem by any means. Any errors that it generates should be mapped into a boost::system::error_code
, but I don't find anything like it in boost/system/error_code.hpp
, so I'm at a loss as to what exactly it is supposed to mean.
But, after looking through the code for boost 1.39, assign
is eventually handed off to either detail::reactive_socket_service< Protocol, Reactor >.assign
(or detail::win_iocp_socket_service<Protocol>
, if you're using windows). It can only be producing an error in two places in boost/asio/detail/reactive_socket_service.hpp
:
if (is_open(impl))
{
ec = boost::asio::error::already_open;
return ec;
}
or
if (int err = reactor_.register_descriptor(
native_socket, impl.reactor_data_))
{
ec = boost::system::error_code(err,
boost::asio::error::get_system_category());
return ec;
}
Since, you're not getting an already_open
error, the error must from the second bit of code. The reactor type comes from a sequence of ifdef
/elif
pairs in boost/asio/stream_socket_service.hpp
, and of those available only the register_descriptor
function in epoll_reactor
can throw any error (and of course detail::win_iocp_socket_service<Protocol>.assign
can, also). The error in epoll_reactor
comes from sys/epoll.h
, specifically:
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
if (result != 0)
return errno;
In the windows implementation, the related code is
if (iocp_service_.register_handle(native_socket.as_handle(), ec))
return ec;
I think this is the origin of your error, but honestly, I can't trace it past this point.