我正在Linux上编写C ++应用程序。我的应用程序有一个UDP服务器,它在某些事件上向客户端发送数据。 UDP服务器还从客户端接收一些反馈/确认。
为了实现这个应用程序,我使用了一个UDP Socket(例如int fdSocket
)来发送和接收来自所有客户端的数据。我将这个socked绑定到端口8080并将套接字设置为NON_BLOCKING模式。
我创建了两个线程。在一个线程中,我等待某个事件发生,如果发生事件,那么我使用fdsocket将数据发送到所有客户端(在for循环中)。
在另一个线程中,我使用fdSocket
从客户端(recvfrom()
)接收数据。此线程计划每4秒运行一次(即每4秒调用recvfrom()
以从套接字缓冲区中检索数据。由于它处于非阻塞模式,recvfrom()
函数将立即返回没有UDP数据可用,然后我会睡4秒钟。
来自所有客户端的UDP反馈/确认具有固定的有效负载,其大小为20字节。
现在我有两个与此实施相关的问题:
我尝试使用函数调用fdsocket
获取套接字(getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);
)的Linux套接字缓冲区大小。从这个函数我发现我的套接字缓冲区大小是110592.但我不清楚将在这个套接字缓冲区中存储什么数据:它是否只存储UDP有效载荷或整个UDP数据包或事件整个以太网数据包?我提到这个link来得到一些想法,但感到困惑。
目前我的代码有点脏,我会在这里清理并发布。
以下是我在发布此问题之前提到的链接。
答案 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头和应用程序数据,其余属于较低级别。