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

for*_*t17 7 java sockets udp network-programming

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

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

Total number of requests sent from the client : 596951
Run Code Online (Sandbox Code Playgroud)

在我看到的tcp转储中

90640 packets captured
175182 packets received by filter
84542 packets dropped by kernel
Run Code Online (Sandbox Code Playgroud)

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();
        }
Run Code Online (Sandbox Code Playgroud)

内核在程序中丢弃数据包的可能原因是什么?

如何减少它?还有其他实现吗?

从这个链接,从评论中读取,UDP协议丢失的数据包总是会发生在网络到java socket.recieve方法之间.

注意:必须弄清楚捕获的tcpdump数据包中的异常,但是丢弃了大量数据包.

tcpdump中的异常是缺少缓冲区空间,为了知道收到的数据包数量,我使用的是iptraf-ng,它给出了每个端口收到的数据包数:)

Maa*_*oAk 4

多线程

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

但是,如果这只是为了测试,并且您的实际应用程序需要对收到的数据包执行某些操作,则需要将数据包推送到另一个数据包Thread(或它们的池),并立即返回侦听下一个数据包。

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

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

缓冲区大小

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

当数据包到达速度快于使用 receive(DatagramPacket) 接收的速度时,增加 SO_RCVBUF 可能允许网络实现缓冲多个数据包。

然而,这只是一个提示:

网络实现使用 SO_RCVBUF 选项作为底层网络 I/O 缓冲区大小的提示。

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

无关紧要

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

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

编辑:

其他多线程模型

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

3 主题:

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

在里面:

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

B1的While循环:

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

B2 也一样。

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

B1 [--------|---]    [--------|---]
B2          [--------|---]    [--------|---]
Run Code Online (Sandbox Code Playgroud)