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

时间:2012-07-12 11:43:53

标签: c++ linux sockets udp buffer

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

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

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

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

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

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

  1. 使用相同的套接字发送/接收UDP数据是否正确 与Mulitiple客户合作?
  2. 如何在没有UDP套接字缓冲区溢出的情况下找到我的应用程序可以处理的最大UDP反馈/确认数据包数量(因为我每4秒读取一次,如果我 在这4秒钟内收到大量数据包我可能会丢失一些数据包,即。我需要找到能够安全处理的数据包/秒速率吗?
  3. 我尝试使用函数调用fdsocket获取套接字(getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);)的Linux套接字缓冲区大小。从这个函数我发现我的套接字缓冲区大小是110592.但我不清楚将在这个套接字缓冲区中存储什么数据:它是否只存储UDP有效载荷或整个UDP数据包或事件整个以太网数据包?我提到这个link来得到一些想法,但感到困惑。

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

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

    1. Linux Networking
    2. UDP SentTo and Recvfrom Max Buffer Size
    3. UDP Socket Buffer Overflow Detection
    4. UDP broadcast and unicast through the same socket?
    5. Sending from the same UDP socket in multiple threads
    6. How to flush Input Buffer of an UDP Socket in C?
    7. How to find the socket buffer size of linux
    8. How do I get amount of queued data for UDP socket?

3 个答案:

答案 0 :(得分:5)

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

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

阅读Stevens,了解SO_RCVBUF

的说明

答案 1 :(得分:2)

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

答:是的,这是正确的。

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

答:瓶颈可能是网络带宽,CPU或内存。你可以简单地做一个测试,使用一个客户端向服务器发送连续号码的ACK,并验证服务器上是否有丢包。

答案 2 :(得分:2)

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

sysctl net.core.rmem_max

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

sysctl -w net.core.rmem_max=8388608

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

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