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,它给出了每个端口收到的数据包数:)
多线程
您的代码示例在收到数据包后不执行任何操作。如果是这种情况,多线程就帮不了你了。
但是,如果这只是为了测试,并且您的实际应用程序需要对收到的数据包执行某些操作,则需要将数据包推送到另一个数据包Thread(或它们的池),并立即返回侦听下一个数据包。
基本上,您需要最小化两次调用之间的时间socket.receive()。
注意:这不是适用于这种情况的唯一多线程模型。
缓冲区大小
socket.setReceiveBufferSize增加映射到 SO_RCVBUF 的缓冲区大小:
当数据包到达速度快于使用 receive(DatagramPacket) 接收的速度时,增加 SO_RCVBUF 可能允许网络实现缓冲多个数据包。
然而,这只是一个提示:
网络实现使用 SO_RCVBUF 选项作为底层网络 I/O 缓冲区大小的提示。
如果您的设置允许,您还可以直接进入操作系统并更改缓冲区的大小。
无关紧要
注意:仅当您不确定数据包大小是否小于 1024 字节时才阅读此内容。
对于通用数据包来说,您的数据包缓冲区大小似乎很低,这可能会导致错误,因为: 如果数据包大于您的缓冲区,则不会出现错误,它只会忽略溢出的字节。
编辑:
其他多线程模型
注:这是一个想法,不知道是否实际可行。
3 主题:
在里面:
B1的While循环:
B2 也一样。
这是线程图(收到数据包的行):
B1 [--------|---] [--------|---]
B2 [--------|---] [--------|---]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1378 次 |
| 最近记录: |