UDP 服务器套接字缓冲区溢出 [英] UDP Server Socket Buffer Overflow

查看:25
本文介绍了UDP 服务器套接字缓冲区溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a C++ application on Linux. My application has a UDP server which sends data to clients on some events. The UDP server also receives some feedback/acknowledgement back from the clients.

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

To implement this application I used a single UDP Socket(e.g. int fdSocket) to send and receive data from all the clients. I bound this socked to port 8080 and have set the socket into NON_BLOCKING mode.

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

I created two threads. In one thread I wait for some event to happen, if an event occurs then I use the fdsocket to send data to all the clients(in a for loop).

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

In the another thread I use the fdSocket to receive data from clients (recvfrom()). This thread is scheduled to run every 4 seconds (i.e. every 4 seconds it will call recvfrom() to retrieve the data from the socket buffer. Since it is in NON-BLOCKING mode the recvfrom() function will return immediately if no UDP data is available, then I will go to sleep for 4 secs).

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

The UDP Feedback/Acknowledge from all the clients has a fixed payload whose size is 20bytes.

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

Now I have two questions related to this implementation:

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

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

I tried to get the Linux Socket Buffer size for my socket (fdsocket) using the function call getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);. From this function I discover that my Socket Buffer size is 110592. But I am not clear as what data will be stored in this socket buffer: will it store only the UDP Payload or Entire UDP Packet or event the Entire Ethernet Packet? I referred this link to get some idea but got confused.

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

Currently my code it little bit dirty , I will clean and post it soon here.

以下是我在发布此问题之前参考的链接.

The following are the links I have referred before posting this question.

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

推荐答案

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

Having socket reading at fixed interval of four seconds definitely sets you up for losing packets. The conventional tried-and-true approach to non-blocking I/O is the de-multiplexer system calls select(2)/poll(2)/epoll(7). See if you can use these to capture/react to your other events.

另一方面,由于你已经在使用线程,你可以阻塞 recv(2) 没有那四秒钟的睡眠.

On the other hand, since you are already using threads, you can just do blocking recv(2) without that four second sleep.

阅读史蒂文斯 用于说明SO_RCVBUF.

这篇关于UDP 服务器套接字缓冲区溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆