【发布时间】: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 秒超时一次(因此可以执行任何服务控制请求,例如停止)。我在想正在发生的事情是:
-
UDP 数据包在 15 秒超时和再次开始侦听之间到达。
-
该数据包在另一个 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