“An existing connection was forcibly closed by the remote host” when listening for incoming data

跟風遠走 提交于 2019-12-11 12:54:05

问题


When working with boost asio, I've stumbled upon some weird behavior, which I don't quite understand. I wrote a minimal test-program to replicate the problem:

#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;
}

If the destination endpoint for the 'send_to'-call exists and is listening, this program runs just fine. The data is sent correctly, and it then waits for incoming data.

However, if the destination endpoint doesn't exist, the behavior is rather unexpected. The 'send_to'-call still dispatches the data without any errors, but when trying to receive data, the 'receive'-call immediately returns, and I'm getting a "An existing connection was forcibly closed by the remote host" error. This doesn't make any sense to me. First of all, there is no remote host, since there is no data being sent to the listener port. Secondly, from what I understand, the receiving- and the sending-part in this program should be completely independent, and shouldn't affect each other at all. Am I wrong in that assumption?

// Edit:

I've just realized that there's another reason why that message doesn't make any sense. I'm using the UDP procotol, which is connectionless, so what 'connection' was closed?


回答1:


While UDP is often referred to as a connectionless protocol, the context implies a stateless protocol. As such, UDP is permitted to return some connect-related error messages:

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.

The Winsock recvfrom() function documents that for UDP, the function will error with WSAECONNRESET if a prior send operation resulted in an ICMP Port Unreachable message:

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



来源:https://stackoverflow.com/questions/34224443/an-existing-connection-was-forcibly-closed-by-the-remote-host-when-listening-f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!