C++ windows多主机服务器上的udp点对点通信

C++ windows多主机服务器上的udp点对点通信,c++,windows,sockets,udp,boost-asio,C++,Windows,Sockets,Udp,Boost Asio,在我的多播接收器应用程序中,我加入一个组并成功接收多播数据。 此外,还有一个用于填补任何空白的api。这使用udp。当检测到间隙时,发送重新传输请求。有一个线程专门用于接收和处理响应请求返回的udp数据报。 这一切在一台只有一个接口卡的windows机器上都很好地工作。现在,我们需要让它在一台有两个网卡的多主机机器上运行。 为了使多播正常工作,我们必须添加路由,以便应用程序将连接发送到正确的NIC。同样,这部分工作正常 但是,点对点udp receive_from方法在输入时立即抛出错误。我的理

在我的多播接收器应用程序中,我加入一个组并成功接收多播数据。 此外,还有一个用于填补任何空白的api。这使用udp。当检测到间隙时,发送重新传输请求。有一个线程专门用于接收和处理响应请求返回的udp数据报。 这一切在一台只有一个接口卡的windows机器上都很好地工作。现在,我们需要让它在一台有两个网卡的多主机机器上运行。 为了使多播正常工作,我们必须添加路由,以便应用程序将连接发送到正确的NIC。同样,这部分工作正常

但是,点对点udp receive_from方法在输入时立即抛出错误。我的理解是,sender_端点是用方法本身初始化的。我是否需要为此udp套接字执行一些特殊操作,以避免在输入时抛出错误?我需要以某种方式绑定套接字还是在主机级别设置特殊路由? 任何帮助都将不胜感激

下面是返回的错误: 错误:reRequestMoldUdp64::WaitForResponse获取错误:提供的参数无效

boost::asio::ip::address    m_targetIP;     
short                       m_port;
udp::endpoint           m_receiver_endpoint;
m_receiver_endpoint.address(m_targetIP);
m_receiver_endpoint.port(m_port);   

if (!m_socket.is_open()) {  
        openUdpSocket();
}

while (1)
{
        m_last_ReceiveLen = 0;
        udp::endpoint sender_endpoint;

        try {
            //m_last_ReceiveLen = m_socket.receive_from( (boost::asio::buffer(m_Buffer, max_length)), sender_endpoint);
            m_last_ReceiveLen = m_socket.receive_from( (boost::asio::buffer(m_Buffer, max_length)), sender_endpoint, 0, ec);
            if (ec) {
                _snprintf(logBuf, sizeof(logBuf), "%s got error:%s", __FUNCTION__, ec.message().c_str());
                MyLog(LOG_ERROR, logBuf);
                myExit(__FILE__, __LINE__, 1);  
            }
        }

        catch (std::exception& e) {                 
            _snprintf(logBuf, sizeof(logBuf), "INFO:%s sender_endpoint.address[%s] error:[%s]",
                            __FUNCTION__, 
                            sender_endpoint.address().to_string().c_str(),
                            e.what());
            MyLogAlways(logBuf);
            if (!m_socket.is_open()) {  
                openUdpSocket();
            }           
            if (++m_waitForResponseNTRetryCnt > 100) {
                myExit(__FILE__, __LINE__, 1);          
            }
            else {
                Sleep(100);     // 100 ms
                continue;           
            }
        }
        std::string dummyStr;
        const UINT64 dummySeqno(0);
        udpResponseAPI(BuildMap,dummySeqno, dummyStr);
    }
}

void reRequestMoldUdp64::openUdpSocket()
{
    char logBuf[512];

    if (!m_socket.is_open()) {      
        m_socket.open(udp::v4(), m_Error);
    }
    else {
        return;
    }   

    if (!m_socket.is_open()) {      
        _snprintf(logBuf, sizeof(logBuf), "%s udp socket didn't reopen error:[%s]", __FUNCTION__, m_Error.message().c_str());
        MyLog(LOG_ERROR, logBuf);       
    }
    else {          
        _snprintf(logBuf, sizeof(logBuf), "%s udp socket successfully opened", __FUNCTION__);
        MyLogAlways(logBuf);
    }
}
//----------------------------------------------------------------------------------------------------
void reRequestMoldUdp64::sendRequest(std::string request)
{   
    MyLog("INFO:Begin sendRequest");

    m_lastRequestSent = request;

    char myBuff[128];
    int len(request.length());
    memcpy(myBuff, request.c_str(), len);   
#if 0
    _snprintf(logBuf, sizeof(logBuf), "INFO:Before sendto() len:%d ip:%s port:%hu",
                len,
                m_receiver_endpoint.address().to_string().c_str(),
                m_receiver_endpoint.port()
                );

    MyLogAlways(logBuf);
#endif
    _snprintf(logBuf, sizeof(logBuf),"%s sending udp rerequest to:%s", __FUNCTION__, 
                                                m_receiver_endpoint.address().to_string().c_str());
    MyLogAlways(logBuf);

    if (m_socket.is_open()) {
        m_socket.send_to(boost::asio::buffer(myBuff, len), m_receiver_endpoint);    
    }
    else {
        m_socket.open(udp::v4(), m_Error);
        m_socket.send_to(boost::asio::buffer(myBuff, len), m_receiver_endpoint);    
        MyLogAlways("ERR:reRequest socket is not open");
    }

}

您不需要添加路由,您应该能够将套接字绑定到所需的NIC,然后让套接字加入多播组。Remy,多播代码工作正常。这是用于udp点对点通信的另一个套接字等。此代码在单独的线程上运行,用于在丢弃多播数据包时填补空白。这并不否定我所说的。在使用代码后,我发现我需要做两件事才能使其正常工作。1) 为ip/端口2初始化senderEndpoint)更重要的是,在调用构造函数的初始值设定项列表中执行此操作。在读取侦听套接字之前,您必须始终
bind()
a侦听套接字。它不仅需要知道要侦听的NIC,还需要知道要侦听的端口号。如果不先建立接收端口号,则无法使用
receive\u from()