繁体   English   中英

UDP服务器套接字缓冲区溢出

[英]UDP Server Socket Buffer Overflow

我正在Linux上编写C ++应用程序。 我的应用程序有一个UDP服务器,它在某些事件上向客户端发送数据。 UDP服务器还从客户端接收一些反馈/确认。

为了实现这个应用程序,我使用了一个UDP Socket(例如int fdSocket )来发送和接收来自所有客户端的数据。 我把它绑定到端口8080并将套接字设置为NON_BLOCKING模式。

我创建了两个线程。 在一个线程中,我等待某个事件发生,如果发生事件,那么我使用fdsocket将数据发送到所有客户端(在for循环中)。

在另一个线程中,我使用fdSocket从客户端接收数据( recvfrom() )。 该线程计划每4秒运行一次(即每4秒调用一次recvfrom()以从套接字缓冲区中检索数据。由于它处于NON-BLOCKING模式,如果没有UDP数据, recvfrom()函数将立即返回可用,然后我会睡4秒)。

来自所有客户端的UDP反馈/确认具有固定的有效载荷,其大小为20字节。

现在我有两个与此实现相关的问题:

  1. 使用相同的套接字与Mulitiple客户端发送/接收UDP数据是否正确?
  2. 如何在没有UDP套接字缓冲区溢出的情况下找到我的应用程序可以处理的UDP反馈/确认数据包的最大数量(因为我每4秒读取一次,如果我在这4秒内收到大量数据包,我可能会丢失一些数据包,即。我需要找到我能安全处理的数据包/秒的速率)?

我尝试使用函数调用getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);获取我的套接字( fdsocket )的Linux套接字缓冲区大小getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m); 从这个函数我发现我的套接字缓冲区大小是110592.但我不清楚将在这个套接字缓冲区中存储什么数据:它是否只存储UDP有效载荷或整个UDP数据包或事件整个以太网数据包? 我提到这个链接是为了得到一些想法,但感到困惑。

目前我的代码有点脏,我会在这里清理并发布。

以下是我在发布此问题之前提到的链接。

  1. Linux网络
  2. UDP SentTo和Recvfrom最大缓冲区大小
  3. UDP套接字缓冲区溢出检测
  4. UDP通过同一个套接字广播和单播?
  5. 从多个线程中的相同UDP套接字发送
  6. 如何在C中刷新UDP套接字的输入缓冲区?
  7. 如何找到linux的socket缓冲区大小
  8. 如何获取UDP套接字的排队数据量?

以4秒的固定间隔读取套接字肯定会让您丢失数据包。 对于非阻塞I / O的传统的经过验证的方法是解复用器系统调用select(2) / poll(2) / epoll(7) 看看你是否可以使用这些来捕捉/回应你的其他事件。

另一方面,由于您已经在使用线程,因此您可以在没有四秒睡眠的情况下阻止recv(2)

阅读史蒂文斯SO_RCVBUF解释。

问:使用相同的套接字与Mulitiple客户端发送/接收UDP数据是否正确?

答:是的,这是对的。

问:如何在没有UDP套接字缓冲区溢出的情况下找到我的应用程序可以处理的UDP反馈/确认数据包的最大数量(因为我每4秒读取一次,如果我在这4秒内收到大量数据包,我可能会丢失一些数据包,即。,I需要找到率:noofpackets / sec我可以安全处理)?

答:瓶颈可能是网络带宽,CPU或内存。 您可以使用向连续编号的服务器发送ACK的客户端进行测试,并验证服务器是否有丢包。

您可以看到允许的最大缓冲区大小:

sysctl net.core.rmem_max

您可以通过以下方式设置可以使用的最大缓冲区大小:

sysctl -w net.core.rmem_max=8388608

您还可以使用setsockopt并更改SO_RCVBUF,在运行时设置缓冲区大小(不超过上述最大值)。 您可以通过查看/ proc / net / udp来查看缓冲级别。

缓冲区用于存储UDP头和应用程序数据,其余属于较低级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM