我的客户端以高速率发送udp数据包。 我确定我的Java应用程序层不会收到客户端发送的所有udp数据包,原因是Wireshark中接收到的数据包的数量与我的Java应用程序不匹配。 因为Wireshark接收到更多的udp数据包,所以我确定udp数据包不会在网络中丢失。
代码在这里:
在一个线程中接收数据包并提供给A(:,1) = x(:);
A(:,2) = y(:);
,而在另一个线程中,消耗LinkedBlockingQueue
的数据包,然后在一个线程上调用LinkedBlockingQueue
rx-java主题。
onNext
主机操作系统:socket = new DatagramSocket(this.port);
socket.setBroadcast(true);
socket.setReceiveBufferSize(2 * 1024 * 1024);
// thread-1
while (true) {
byte[] bytes = new byte[532];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
try {
this.socket.receive(packet);
queue.offer(
new UdpPacket(
packet.getPort(), packet.getAddress().getHostAddress(), packet.getData()));
} catch (IOException e) {
e.printStackTrace();
}
}
// thread-2
UdpPacket packet;
while ((packet = queue.take()) != null) {
this.receiveMessageSubject.onNext(packet);
}
答案 0 :(得分:0)
很难给出一个直接的答案,但是根据我在Java中处理UDP消息的经验,提高处理消息的性能确实很重要,尤其是在处理大量数据时。
这是我要考虑的一些事情:
1)您正确地在其他队列上处理UDP消息。但是,队列的大小有限。您是否能够快速处理消息?否则,队列将填满,您将阻塞while循环。如果是这种情况,一些简单的日志记录可能会让您知道。将它们放在一个队列中,可以在不同的步骤中将它们弹出,这很了不起,但您还需要确保处理速度快并且队列不会填满。
2)您所有的数据报是否都小于532字节?也许是由于较大的邮件未填充缓冲区而造成一些损失。
希望这会有所帮助,
答案 1 :(得分:0)
最近我用另一种语言遇到了类似的问题。我不确定它是否在Java中也可以使用,但这可能对您有所帮助。
因此,当数据包进入套接字时,它们将被缓冲,并且您已经设置了缓冲区大小,但是即使缓冲区可能容纳更多数据包,您仍然仅读取单个数据包。当您一次处理一个数据报时,缓冲区将填满甚至更多,最终当缓冲区满时,由于无法存储更多数据报,数据可能会丢失。
我在documentation中检查了DatagramSocket
Receives a datagram packet from this socket
我不确定您需要在Java中调用哪些函数,但这是我正在使用的一小段代码。
while (!m_server->BufferEmpty()) {
std::shared_ptr<Stream> inStream = std::make_shared<Stream>();
std::vector<unsigned char>& buffer = inStream->GetBuffer();
boost::asio::ip::udp::endpoint senderEndpoint = m_server->receive(boost::asio::buffer(buffer),
boost::posix_time::milliseconds(-1), ec);
if (ec)
{
std::cout << "Receive error: " << ec.message() << "\n";
}
else
{
std::unique_ptr<IPacketIn> incomingPacket = std::make_unique<IPacketIn>();
incomingPacket->ReadHeader(inStream);
m_packetProcessor->ProcessPacket(incomingPacket, senderEndpoint);
incomingPacket.reset();
}
++packetsRead;
inStream.reset();
}
这基本上是说,如果套接字在其缓冲区中有当前帧的任何数据,请继续读取数据报,直到缓冲区为空。
不确定LinkedBlockingQueue
的工作方式,但是如果两个线程都试图同时访问它,这也可能会引起一些问题。在您的UDP读取线程中,您可能会被阻塞一段时间,然后在这段时间内可能会收到数据包。