2012-07-12 161 views
4

我正在Linux上编写C++应用程序。我的应用程序有一个UDP服务器,它在某些事件中向客户端发送数据。 UDP服务器还收到来自客户端的一些反馈/确认。UDP服务器套接字缓冲区溢出

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

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

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

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

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

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

我尝试使用函数调用getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);获取我的套接字(fdsocket)的Linux套接字缓冲区大小。从这个函数中我发现我的Socket缓冲区大小是110592.但是我不清楚这个数据将被存储在这个套接字缓冲区中:它将只存储UDP Payload还是整个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?
+1

为什么只有每4秒?为什么不只是让这个线程坐在一个'select()'调用等待数据? – Collin 2012-07-12 12:17:20

+0

@Collin由于UDP不可靠,我们实现了以下机制。对于发送给客户端的每个UDP数据包,我都希望从客户端返回一个确认数据包(带有固定字符串的简单UDP数据包)。如果我没有收到来自客户端的确认数据包,那么我将在4秒后再次发送数据包 – 2012-07-12 12:26:34

+1

好吧,但是使用该设置,服务器即使在没有数据包时也会丢失数据包。在客户端读取套接字之后发送数据包时会发生什么?随着网络时间的推移,服务器会认为即使存在,也不会有任何回应。仍然没有理由不立即回应。您可以使用TCP或类似的东西来代替滚动自己的可靠性:http://udt.sourceforge.net/ – Collin 2012-07-12 12:40:20

回答

3

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

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

阅读Stevens以获取SO_RCVBUF的解释。

+0

以及此发布的评论[EJP](http://stackoverflow.com/users/207421/ejp)给出了一个清晰的想法。 – 2012-07-13 05:31:47

2

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

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

2

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

sysctl net.core.rmem_max 

您可以设置可以使用的最大缓冲区大小:

sysctl -w net.core.rmem_max=8388608 

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

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