2 回答
![?](http://img1.sycdn.imooc.com/545865b000016a9202200220-100-100.jpg)
TA贡献1909条经验 获得超7个赞
我最近在另一种语言中遇到了类似的问题。我不确定它在 Java 中是否同样有效,但这可能对您有所帮助。
因此,当数据包进入套接字时,它们被缓冲并且您已经设置了缓冲区大小,但是您仍然只读取一个数据包,即使缓冲区可能容纳更多。当您一次处理一个数据报时,您的缓冲区会越来越多,最终当它满时,数据可能会丢失,因为它无法存储更多数据报。
我检查了文档的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 读取线程中,您可能会被阻塞一段时间,然后在此期间可能会收到数据包。
![?](http://img1.sycdn.imooc.com/533e4d510001c2ad02000200-100-100.jpg)
TA贡献1827条经验 获得超8个赞
很难给出一个直接的答案,但根据我在 Java 中处理 UDP 消息的经验,提高处理消息的性能确实很重要,尤其是处理大量数据时。
所以这里有一些我会考虑的事情:
1) 在不同的队列上处理 UDP 消息是正确的。但是,队列的大小有限。您是否设法快速处理消息?否则,队列会填满,而您将阻塞 while 循环。如果是这种情况,一些简单的日志记录可以让您知道。把它们放在一个队列中,在那里它们可以在不同的步骤中被排出是很棒的,但你还需要确保处理速度很快并且队列不会填满。
2) 你所有的数据报都小于 532 字节吗?可能由于未填充缓冲区的较大消息而发生一些损失。
希望这可以帮助,
添加回答
举报