У меня недавно была похожая проблема на другом языке.Я не уверен, что он работает так же в 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 вы можете быть заблокированы на некоторое время, а затем пакеты могут быть получены в течение этого времени.