请考虑以下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消息。
我在这里做什么错了?
答案 0 :(得分:2)
UDP在设计上是无连接的。因此,无论收件人是否在监听,该程序都应发送5条UDP消息。
第一个并不意味着第二个。使用UDP,不能保证错误报告,这与保证没有错误报告完全不同。通常,到达没有侦听器的端口的数据包将触发ICMP端口不可达消息返回发件人,并且大多数Sockets API实现都会在下次尝试传输到同一目的地时向应用程序报告。通过环回,对于网络堆栈而言,检测错误甚至更加容易。