java - 一个 java UDP 套接字可以处理多少个请求?

标签 java sockets network-programming udp

我需要构建一个可以处理 ~10_000 个请求/秒的 UDP 服务器。从以下代码开始,测试 Java 套接字是否可以处理这些请求数。

我用大约 9000 个请求轰炸服务器一分钟,

Total number of requests sent from the client : 596951

在我看到的 tcp 转储中

90640 packets captured
175182 packets received by filter
84542 packets dropped by kernel

UDP 服务器代码:

try (DatagramSocket socket = new DatagramSocket(port)) {
            System.out.println("Udp Server started at port :" + port);


            while (true) {
                byte[] buffer = new byte[1024];
                DatagramPacket incomingDatagramPacket = new DatagramPacket(buffer, buffer.length);
                try {
                    socket.receive(incomingDatagramPacket);
                    LinkedTransferQueue.add(incomingDatagramPacket);
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;

                }


            }

        } catch (SocketException e) {
            e.printStackTrace();
        }

What is the the probable cause kernel dropping the packets in program this simple ?

How to reduce it ? Any other implementation ?

从这里link ,从评论中读到,即使在网络与 java socket.recieve 方法之间,UDP 协议(protocol)的数据包丢失也总是会发生。

注意:抓到的tcpdump包有异常要搞清楚,但是掉包的数量还是挺多的。

tcpdump 中的异常是 lack of buffer space ,为了知道收到的数据包数量,我使用了 iptraf-ng它给出了每个端口接收到的数据包数量:)

最佳答案

多线程

您的代码示例在收到数据包后不执行任何操作。如果是这样,多线程就帮不了你了。

然而,如果这只是为了测试,而您的实际应用程序需要对接收到的数据包做一些事情,您需要将数据包推送到另一个 Thread(或它们的池)并立即返回监听下一个数据包。

基本上,您需要最小化 socket.receive() 的两次调用之间的时间。

注意:这不是可用于这种情况的唯一多线程模型。

缓冲区大小

使用映射到 SO_RCVBUF 的 socket.setReceiveBufferSize 增加缓冲区大小:

Increasing SO_RCVBUF may allow the network implementation to buffer multiple packets when packets arrive faster than are being received using receive(DatagramPacket).

然而,这只是一个提示:

The SO_RCVBUF option is used by the the network implementation as a hint to size the underlying network I/O buffers.

如果您的设置允许,您也可以直接转到操作系统并更改缓冲区的大小。

不相关

注意:仅当您不确定数据包大小是否小于 1024 字节时才阅读此内容。

对于通用数据包,您的数据包缓冲区大小似乎较小,这可能会导致错误,因为:如果数据包大于您的缓冲区,则不会出现错误,它只会忽略溢出的字节。

编辑:

其他多线程模型

注:这是一个想法,不知道是否真的可行。

3 个线程:

  • 线程A:处理数据包
  • 线程B1:接收数据包
  • 线程B2:接收数据包

初始化:

  • 原子计数器设置为 0
  • B1 正在接收,B2 正在等待。

B1 的 While 循环:

  • while 计数器 > 0 等待
  • 计数器 += 1
  • 收到包裹
  • 计数器 -= 1
  • 唤醒B2
  • 将数据包推送到A的队列

B2 也一样。

这是线程图(已收到数据包的行):

B1 [--------|---]    [--------|---]
B2          [--------|---]    [--------|---]

关于java - 一个 java UDP 套接字可以处理多少个请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46023098/

相关文章:

ios - 从 URLRequestConvertible 扩展时设置多部分请求的最佳方法是什么

java - 使用流将 HashMap<String,List<String>> 转换为 HashMap<Object,List<String>>

java - GUI 不适用于自定义 AbstractTableModel。错误 "Unknown Source"

java - 在eclipse路径问题中使用java调用python

java - 在正则表达式中提取文本

c - 我应该在 select() EBADF 上断言失败吗?

c++ - 使用套接字 send()/recv()(winsock) 回显服务器/客户端消息截断

C# - 避免获取 SocketException

c# - 使用 TPL ping 网络中的所有计算机

C++访问url日志