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

Din*_*.R. 6 c++ sockets linux buffer udp

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

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

我创建了两个线程.在一个线程我等待一些事件发生,如果有事件发生,然后我用fdsocket将数据发送到所有客户端(在for循环).

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

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

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

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

我尝试fdsocket使用函数调用获取socket()的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套接字的排队数据量?

Nik*_*sov 5

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

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

阅读史蒂文斯的解释SO_RCVBUF.


per*_*eal 5

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

sysctl net.core.rmem_max
Run Code Online (Sandbox Code Playgroud)

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

sysctl -w net.core.rmem_max=8388608
Run Code Online (Sandbox Code Playgroud)

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

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