【问题标题】:Always listening UDP Server一直在监听 UDP 服务器
【发布时间】:2021-11-05 18:18:52
【问题描述】:

大家下午好,

我一直在制作一个 UDP 服务器,用于在我的 Windows 服务器上收集指标(SNMP 在 Windows 上不准确,因为它没有 64 位计数器)。服务器运行在Windows服务器上,客户端运行在Linux监控盒上。

我已将它设置为作为服务运行,它运行良好,只是每隔一段时间,没有从 Linux 机器接收到 UDP 数据包。我正在使用以下代码来接收 UDP 数据包:

bytes_received = recvfrom(serverSocket, serverBuf, serverBufLen, 0, (SOCKADDR*)&SenderAddr, &SenderAddrSize);

套接字设置为每 15 秒超时一次(因此可以执行任何服务控制请求,例如停止)。我在想正在发生的事情是:

  1. UDP 数据包在 15 秒超时和再次开始侦听之间到达。

  2. 该数据包在另一个 UDP 数据包到达(对于不同的度量标准)之后的几分之一秒内到达,并且它已经开始启动一个进程以将数据包发回,因此它还没有在 recvfrom 处。

(我的两个假设都基于我的假设,即它仅在处于 recvfrom 时才等待数据包)。

我可能会转而使用 TCP 来解决这个问题,但由于信息对时间敏感,我更愿意继续使用 UDP 以提高速度。

是否有办法将传入的数据包排队并进行处理,或者我最好改为查看 TCP?

【问题讨论】:

  • 这是关于 UDP 的问题之一,它不可靠,您可能会丢失数据包。或者他们可能以错误的顺序到达。为了帮助您解决第一个问题,请使用 polling 函数来确定在调用 recvfrom 之前是否有可接收的数据包。
  • "套接字设置为每 15 秒超时一次(因此可以执行任何服务控制请求,如停止)" - 您是否在同一线程上处理套接字和 SCM ?如果是这样,请将它们移动到单独的线程中。 “UDP 数据包在 15 秒超时和再次开始侦听之间到达......因此它还没有在 recvfrom 处” - 这很好。套接字缓冲传入的数据包。但是,如果你用太多的数据包溢出了一个 UDP 套接字的缓冲区,后续的数据包将会被丢弃,所以你可能需要使用setsockopt(SO_RCVBUF) 来增加缓冲区的大小。
  • "我的这两个假设都基于我的假设,即它只在 recvfrom 时等待一个数据包" - 这是不正确的。见我之前的评论。 “无论如何都要排队传入的数据包” - 它已经在这样做了。
  • 我以为缓冲区只用于recvfrom,没有套接字。查看我的代码serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 和我的绑定int binder = bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));,我看不到缓冲区在哪里发挥作用。
  • @chris-p-tech 缓冲区位于套接字本身中。内核在数据到达网络时将其放入缓冲区。 recvfrom() 只是从缓冲区中提取数据,如果需要,则等待数据到达。看来你需要一些关于网络编程的好书。

标签: c++ sockets networking udp


【解决方案1】:

如果第一个数据包在 2 秒后没有得到响应,我最终提出了传输 UDP 数据包的想法。到目前为止效果很好。

编辑:

它正在询问代码:

std::string returnMsg;
returnMsg = "CRITICAL - No packet recieved back.";
int i = 0;

while(returnMsg == "CRITICAL - No packet recieved back.")  {
    if(i == 5) {
        std::cout << "CRITICAL - No packet recieved back." << "\n";
        return 2;
    }
    //std::cout << "Try " << i << "\n";

    // Now lets send the message
    send_message(args[2],message.c_str());

    // Now lets wait for response
    returnMsg = recieve_message();
    
    i++;
}

recieve_message 函数在超时发生时返回“CRITICAL - 未收到数据包”。

【讨论】:

  • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
  • 深思:如果返回消息在传输过程中丢失了怎么办?
  • 如果 5 次都没有得到响应,则输出 CRITICAL MESSAGE 并返回 2。
猜你喜欢
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 2011-05-20
  • 2019-08-08
  • 1970-01-01
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多