Ralf Globisch
2013-02-23 20:27:25 UTC
Hi,
I have a fairly large application that works as desired on Linux.
I've recently compiled it on Windows 7 using VC2012 and boost
asio 1.52 and run into a strange issue:
An async_receive_from followed by an async_send_to on the same
UDP socket results in the read completion handler being called with
boost::system::error_code 10061:
"No connection could be made because the target machine actively refused it"
*if* the send destination is another port on the local host.
If the packet is sent to another machine, the read completion handler is not called.
After the read completion handler, the write completion handler is called with no error.
The following code replicates the issue:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost::asio;
void read_completion_handler(const boost::system::error_code& ec, std::size_t bytes_received)
{
if (!ec)
cout << "Received " << bytes_received << " successfully" << endl;
else
cout << "Error: " << ec.message() << endl;
}
void write_completion_handler(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
if (!ec)
cout << "Wrote " << bytes_transferred << " successfully" << endl;
else
cout << "Error: " << ec.message() << endl;
}
int main(int argc, char** argv)
{
enum
{
max_length = 1500,
out_length = 100
};
// buffer for incoming data
char data[max_length];
// outgoing data
char out_data[out_length];
// sender endpoint
ip::udp::endpoint sender_endpoint;
// for sending packets
// ip::udp::endpoint destination(ip::address::from_string("127.0.0.1"), 5004);
// ip::udp::endpoint destination(ip::address::from_string("130.149.228.121"), 5004);
ip::udp::endpoint destination(ip::address::from_string("192.168.179.48"), 55555);
io_service ioService;
ip::udp::socket socket(ioService, ip::udp::endpoint(ip::udp::v4(), 49170));
socket.async_receive_from(
buffer(data, max_length), sender_endpoint,
boost::bind(&read_completion_handler,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
socket.async_send_to( boost::asio::buffer(out_data, out_length),
destination,
boost::bind(&write_completion_handler,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
ioService.run();
cout << "Done" << endl;
return 0;
}
On linux this is never an issue. Does anyone have an explanation or a work-around?
As far as I know, simultaneous reads and writes on the same socket
should be ok or is this not the case on Windows? Why the change in
behaviour if localhost is the destination?
Thanks for any help,
Ralf
I have a fairly large application that works as desired on Linux.
I've recently compiled it on Windows 7 using VC2012 and boost
asio 1.52 and run into a strange issue:
An async_receive_from followed by an async_send_to on the same
UDP socket results in the read completion handler being called with
boost::system::error_code 10061:
"No connection could be made because the target machine actively refused it"
*if* the send destination is another port on the local host.
If the packet is sent to another machine, the read completion handler is not called.
After the read completion handler, the write completion handler is called with no error.
The following code replicates the issue:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost::asio;
void read_completion_handler(const boost::system::error_code& ec, std::size_t bytes_received)
{
if (!ec)
cout << "Received " << bytes_received << " successfully" << endl;
else
cout << "Error: " << ec.message() << endl;
}
void write_completion_handler(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
if (!ec)
cout << "Wrote " << bytes_transferred << " successfully" << endl;
else
cout << "Error: " << ec.message() << endl;
}
int main(int argc, char** argv)
{
enum
{
max_length = 1500,
out_length = 100
};
// buffer for incoming data
char data[max_length];
// outgoing data
char out_data[out_length];
// sender endpoint
ip::udp::endpoint sender_endpoint;
// for sending packets
// ip::udp::endpoint destination(ip::address::from_string("127.0.0.1"), 5004);
// ip::udp::endpoint destination(ip::address::from_string("130.149.228.121"), 5004);
ip::udp::endpoint destination(ip::address::from_string("192.168.179.48"), 55555);
io_service ioService;
ip::udp::socket socket(ioService, ip::udp::endpoint(ip::udp::v4(), 49170));
socket.async_receive_from(
buffer(data, max_length), sender_endpoint,
boost::bind(&read_completion_handler,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
socket.async_send_to( boost::asio::buffer(out_data, out_length),
destination,
boost::bind(&write_completion_handler,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
ioService.run();
cout << "Done" << endl;
return 0;
}
On linux this is never an issue. Does anyone have an explanation or a work-around?
As far as I know, simultaneous reads and writes on the same socket
should be ok or is this not the case on Windows? Why the change in
behaviour if localhost is the destination?
Thanks for any help,
Ralf
--
This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard.
The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.
This message has been scanned for viruses and dangerous content by MailScanner,
and is believed to be clean.
Please consider the environment before printing this email.
This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard.
The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.
This message has been scanned for viruses and dangerous content by MailScanner,
and is believed to be clean.
Please consider the environment before printing this email.