在循环内使用UDP套接字时,连接被拒绝

时间:2018-06-19 11:46:19

标签: c++ network-programming boost-asio

请考虑以下MWE类foo,该类具有send成员函数,该成员函数允许通过UDP将字符串发送到端口1337上的回送地址:

头文件:foo.h

#include <boost/asio.hpp>

class foo
{
public:

  foo(); // Constructor.
  void send(std::string const& message);

private:

  boost::asio::io_service ios;
  boost::asio::ip::udp::socket sock;
  boost::asio::ip::udp::endpoint endp;
};

实施文件:foo.cc

#include "foo.h"

foo::foo() : sock{ios}, endp{boost::asio::ip::address::from_string("127.0.0.1"), 1337}
{
    sock.connect(endp);
}

void foo::send(std::string const& message)
{
    sock.send(boost::asio::buffer(message));
}

现在,我想使用foo类将字符串Hello, World!\n发送给自己。因此,在主函数中,我实例化了一个foo对象,然后使用for循环调用foo.send() 5次(两次突发之间等待1秒)。

主要功能:

#include "foo.h"
#include <iostream>
#include <chrono>
#include <thread>

int main(int argc, char* argv[])
{
    foo foo;
    for(int i = 0; i<5; i++)
    {
        foo.send("Hello, World!\n");
        std::cout << i << std::endl;

        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    std::cout << "Done" << std::endl;

    return 0;
}

代码成功编译。但是,在运行时,程序崩溃并引发以下错误:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
  what():  send: Connection refused
Aborted (`core' dumped)

Connection refused错误消息非常混乱,因为UDP在设计上是无连接的。因此,无论收件人是否在监听,该程序都应发送5条UDP消息。

我在这里做什么错了?

1 个答案:

答案 0 :(得分:2)

  

UDP在设计上是无连接的。因此,无论收件人是否在监听,该程序都应发送5条UDP消息。

第一个并不意味着第二个。使用UDP,不能保证错误报告,这与保证没有错误报告完全不同。通常,到达没有侦听器的端口的数据包将触发ICMP端口不可达消息返回发件人,并且大多数Sockets API实现都会在下次尝试传输到同一目的地时向应用程序报告。通过环回,对于网络堆栈而言,检测错误甚至更加容易。