C++ windows多主机服务器上的udp点对点通信
在我的多播接收器应用程序中,我加入一个组并成功接收多播数据。 此外,还有一个用于填补任何空白的api。这使用udp。当检测到间隙时,发送重新传输请求。有一个线程专门用于接收和处理响应请求返回的udp数据报。 这一切在一台只有一个接口卡的windows机器上都很好地工作。现在,我们需要让它在一台有两个网卡的多主机机器上运行。 为了使多播正常工作,我们必须添加路由,以便应用程序将连接发送到正确的NIC。同样,这部分工作正常 但是,点对点udp receive_from方法在输入时立即抛出错误。我的理解是,sender_端点是用方法本身初始化的。我是否需要为此udp套接字执行一些特殊操作,以避免在输入时抛出错误?我需要以某种方式绑定套接字还是在主机级别设置特殊路由? 任何帮助都将不胜感激 下面是返回的错误: 错误:reRequestMoldUdp64::WaitForResponse获取错误:提供的参数无效C++ windows多主机服务器上的udp点对点通信,c++,windows,sockets,udp,boost-asio,C++,Windows,Sockets,Udp,Boost Asio,在我的多播接收器应用程序中,我加入一个组并成功接收多播数据。 此外,还有一个用于填补任何空白的api。这使用udp。当检测到间隙时,发送重新传输请求。有一个线程专门用于接收和处理响应请求返回的udp数据报。 这一切在一台只有一个接口卡的windows机器上都很好地工作。现在,我们需要让它在一台有两个网卡的多主机机器上运行。 为了使多播正常工作,我们必须添加路由,以便应用程序将连接发送到正确的NIC。同样,这部分工作正常 但是,点对点udp receive_from方法在输入时立即抛出错误。我的理
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()
。