2012-12-21 125 views
1

我有一個相當大的應用程序,它可以在Linux上按照需要工作。Windows升壓asio:10061在async_receive_from on async_send_to

async_receive_from隨後在讀取完成處理程序相同UDP套接字結果的async_send_to被稱爲與boost::system::error_code 10061:

我使用VC2012和提高ASIO 1.52碰上一個奇怪的問題最近編譯它在Windows 7

無連接可以作出,因爲目標機器積極地拒絕它

如果發送目的地是本地主機上的另一個端口。如果數據包發送到另一臺機器,則不會調用讀取完成處理程序。讀完成處理程序之後,寫入完成處理程序將被調用,且不會發生錯誤。

下面的代碼複製問題:

#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上不是這樣?爲什麼本地主機是目的地的行爲改變?

回答

5

是的,這是大約6個月後,你問這個問題。我甚至不確定我是如何在這裏結束的。我自己遇到了這個問題 - 但好消息是這不是問題。

當某些機器沒有偵聽到您發送消息的端口時,它們會通過ICMP返回目標不可達消息。 Asio將其轉換爲boost :: system :: errc :: connection_refused和/或boost :: system :: errc :: connection_reset。這是一個無意義的錯誤,因爲UDP是無連接的。您可以放心地忽略async_receive_from處理程序中的這兩個錯誤代碼(即,如果返回其中一個錯誤,則只需再次調用async_receive_from)即可。

+1

您好,感謝您的答覆和解釋ASIO錯誤代碼轉換。這就說得通了。很高興知道別人遇到過類似的問題。不過,爲什麼寫入會導致讀取失敗?這是一個asio錯誤?你能對此有所瞭解嗎? – Ralf

+0

你好! 2年後,我找到你的線索。我遇到了同樣的問題! 當主機(通常在同一臺機器上127.0.0.1)嘗試發送數據並且該端口上沒有任何內容偵聽時,UDP似乎會執行此類事情。 發生在C#以及Boost :: Asio C++中。要在C#中修復此問題,您可以編寫以下代碼: byte [] byteTrue = new byte [4]; byteTrue [byteTrue.Length - 1] = 1; m_udpClient.Client.IOControl(-1744830452,byteTrue,null); 對不起,但我不知道一個解決方案爲升壓阿西歐,所以只是做一個特殊情況,並忽略該錯誤 – AndrewVS2013

+0

Niether boost :: system :: errc :: connection_refused pr case boost :: system :: errc :: connection_reset是= 10061 –

1

對於任何人在這方面磕磕絆絆,請閱讀我上面對第一個響應的評論。

但是,如果你是通過任何變化遇到在C#中同樣的問題,使用此代碼擺脫的行爲:

 byte[] byteTrue = new byte[4]; 
     byteTrue[byteTrue.Length - 1] = 1; 
     m_udpClient.Client.IOControl(-1744830452, byteTrue, null);