c++ - "An existing connection was forcibly closed by the remote host"监听传入数据时

标签 c++ windows networking listener boost-asio

在使用 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”调用仍然无误地分派(dispatch)数据,但是当尝试接收数据时,“receive”调用立即返回,并且我收到“现有连接被远程主机强行关闭”错误。这对我来说没有任何意义。首先,没有远程主机,因为没有数据发送到监听器端口。其次,据我了解,这个程序中的接收部分和发送部分应该是完全独立的,根本不应该相互影响。我的假设错了吗?

//编辑:

我刚刚意识到该消息没有任何意义还有另一个原因。我正在使用无连接的 UDP 协议(protocol),那么什么“连接”已关闭?

最佳答案

虽然 UDP 通常被称为无连接协议(protocol),但上下文意味着无状态协议(protocol)。因此,UDP允许返回一些与连接相关的错误消息:

All errors documented for socket or ip may be returned by a send or receive on a UDP socket.

ECONNREFUSED
    No receiver was associated with the destination address. This might be caused by a previous packet sent over the socket.

Winsock recvfrom()函数记录对于 UDP,如果先前的发送操作导致 ICMP 端口无法到达消息,该函数将出错并返回 WSAECONNRESET:

WSAECONNRESET
    [...] On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port Unreachable message.

关于c++ - "An existing connection was forcibly closed by the remote host"监听传入数据时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34224443/

相关文章:

networking - 如何使用 Docker(或 Linux 容器)进行网络仿真?

c++ - 将 OpenBLAS 与 Qt Creator 项目链接

c++ - 使用函数指针作为回调

使用 PROC_THREAD_ATTRIBUTE_PREFERRED_NODE 或 PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY 时的 CreateProcess 问题

windows - 如何将 D 编程语言安装到 C :\Program Files?

html - Windows 和 Macintosh 显示不同的页面

networking - 用于可靠网络连接的实用 NAT 穿越

java - JpcapCaptor.getDeviceList() 返回一个空数组

c++ - 如何将 void (__thiscall MyClass::* )(void *) 转换为 void (__cdecl *)(void *) 指针

c++ - 声明 std::string 变量后,Cout 没有输出