我有一个相当大的应用程序,可以在Linux上按需要运行。 我最近使用VC2012在Windows 7上编译它,并升级asio 1.52,并遇到一个奇怪的问题:
在同一个UDP套接字上的async_receive_from
后跟一个async_send_to
导致读取完成处理程序被调用boost::system::error_code
10061:
由于目标机器主动拒绝,所以不能build立连接
如果发送目的地是本地主机上的另一个端口。 如果数据包发送到另一台机器,则不会调用读取完成处理程序。 读完成处理程序后,写完成处理程序被调用,没有错误。
以下代码复制该问题:
#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: if this localhost, the error occurs ip::udp::endpoint destination(ip::address::from_string("127.0.0.1"), 5004); 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; }
在Linux上这不是一个问题。 有没有人有解释? 据我所知,在同一套接字上同时读写应该没问题,或者在Windows上不是这种情况? 为什么本地主机是目的地的行为改变?
是的,大概在你问这个问题6个月后。 我甚至不确定我是如何在这里结束的。 我自己遇到了这个问题,但好消息是这不是问题。
有些机器没有监听您发送信息的端口时,通过ICMP返回目的地不可达信息。 Asio将其转换为boost :: system :: errc :: connection_refused和/或boost :: system :: errc :: connection_reset。 这是一个无意义的错误,因为UDP是无连接的。 您可以放心地忽略async_receive_from处理程序中的这两个错误代码(即,如果返回其中一个错误,只需再次调用async_receive_from)即可。
对于任何人在这方面磕磕绊绊,阅读我上面的第一个回应的评论。
但是,如果您在C#中遇到同样的问题,请使用以下代码来摆脱这种行为:
byte[] byteTrue = new byte[4]; byteTrue[byteTrue.Length - 1] = 1; m_udpClient.Client.IOControl(-1744830452, byteTrue, null);