在使用boost asio时,我偶然发现了一些奇怪的行为,我不太明白。我写了一个最小的测试程序来复制问题:
#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::udp;
int main(int argc,char *argv[])
{
boost::asio::io_service ioService;
udp::resolver resolver(ioService);
udp::resolver::query queryListen("127.0.0.1","50001");
auto epListen = *resolver.resolve(queryListen);
udp::socket socket(ioService,epListen);
udp::resolver::query querySend("127.0.0.1","55006");
auto epSend = *resolver.resolve(querySend);
boost::system::error_code err;
std::array<char,12> buffer = {'1','2','3','4','5','6','7','8','9','10','11','12'};
socket.send_to(
boost::asio::buffer(&buffer[0],buffer.size()),
epSend,0,err
);
if(!err)
{
std::cout<<"Sent successfully!"<<std::endl;
auto numBytes = socket.receive(
boost::asio::buffer(&buffer[0],buffer.size()),0,
err
);
if(!err)
std::cout<<"Received "<<numBytes<<" bytes successfully!"<<std::endl;
else
std::cout<<"Unable to receive: "<<err.message()<<std::endl; // This is where I'm getting the message "An existing connection was forcibly closed by the remote host"
}
else
std::cout<<"Unable to send: "<<err.message()<<std::endl;
for(;;);
return 0;
}
如果'send_to'调用的目标端点存在且正在侦听,则此程序运行正常。数据正确发送,然后等待传入数据。
但是,如果目标端点不存在,则行为非常意外。 'send_to'调用仍然调度数据而没有任何错误,但是当尝试接收数据时,'receive'调用立即返回,并且我得到“现有连接被远程主机强行关闭”错误。这对我没有任何意义。首先,没有远程主机,因为没有数据被发送到侦听器端口。其次,根据我的理解,该程序中的接收和发送部分应该是完全独立的,并且不应该相互影响。我错了这个假设吗?
//编辑:
我刚刚意识到这个消息没有任何意义的另一个原因。我正在使用无连接的UDP协议,那么“连接”是什么关闭的?
答案 0 :(得分:1)
虽然UDP通常被称为无连接协议,但上下文意味着无状态协议。因此,UDP被允许返回一些与连接相关的错误消息:
socket或ip记录的所有错误都可能由UDP套接字上的发送或接收返回。
ECONNREFUSED
没有接收器与目标地址相关联。这可能是由通过套接字发送的之前的数据包引起的。
Winsock recvfrom()
函数记录了对于UDP,如果先前的发送操作导致ICMP Port Unreachable消息,则该函数将错误WSAECONNRESET
:
WSAECONNRESET
[...]在UDP数据报套接字上,此错误表示先前的发送操作导致ICMP端口无法访问消息。