Я начал свою работу над заранее разработанным Java-приложением, где они имеют дело с java-сокетами. Основная идея проекта - получить данные от клиента на сервере Java-сокетов и обработать их.
Проект разработан с использованием Java NIO ServerSocketChannel.
Теперь в этом сценарии я мог получать от клиента около 70-80 записей в секунду. В то время как, если я использую простой Java ServerSocket (только для целей тестирования), результат увеличивается примерно до 800 повторений.
Почему в обоих случаях такая большая разница? И как я могу изменить ServerSocketChannel для имитации ServerSocket?
Вот моя основная часть обработки,
SocketChannel client = (SocketChannel) key.channel();
if (!key.isReadable()) {
key.cancel();
client.close();
continue;
}
int[] k = (int[]) key.attachment();
if (k[2] == 0) {
ByteBuffer lengthBuffer = ByteBuffer.allocate(2);
int bytesRead = -1;
if (!client.socket().isClosed() && key.isValid()) {
bytesRead = client.read(lengthBuffer);
}
if (bytesRead == -1) {
key.cancel();
client.close();
continue;
}
lengthBuffer.flip();
byte[] bytes = new byte[2];
lengthBuffer.get(bytes, 0, 2);
short length = DRMSDecoder.getShort(bytes);
k[0]++;
k[1] = length;
k[2] = 1;
key.attach(k);
lengthBuffer.clear();
}
else {
try {
int length = k[1];
ByteBuffer dataBuffer = ByteBuffer.allocate(length);
dataBuffer.clear();
System.gc();
int bytesRead = -1;
if (!client.socket().isClosed() && key.isValid()) {
bytesRead = client.read(dataBuffer);
}
if (bytesRead == -1) {
key.cancel();
client.close();
continue;
}
dataBuffer.flip();
Hashtable<String, Object> request = decoder.decode(dataBuffer);
short call_type = (Short) request.get("Call Type");
if (request.get("Call Type") != null && (((Short) request.get("Call Type")) == 78 || ((Short) request.get("Call Type")) == 80)) {
} else if (request.get("Call Type") != null && (((Short) request.get("Call Type")) == 79)) {
key.cancel();
client.close();
}
String message = (String) request.get("Buffer");
handleMessage(message);
}
k[0]++;
k[2] = 0;
key.attach(k);
lastMessageProcessed++;
dataBuffer.clear();
} catch (Exception e) {
// System.out.println(e);
}
}
Я бы начал с удаления всего, что создает новый объект. :П
Кстати, в моей статье есть ссылки на код, который я использовал. Я не использовал селекторы, хотя они не должны сильно замедлять код. ;)
Питер Лоури Спасибо, попробую ваше решение




Разница в блокирующий ввод / вывод против неблокирующего ввода / вывода.
Ссылка: https://medium.com/coderscorner/tale-of-client-server-and-socket-a6ef54a74763
но я уже делаю это server.configureBlocking (false); client.configureBlocking (ложь);
Оба примера блокируют. Неблокирование NIO обычно немного быстрее, но в этом случае NIO работает медленнее. -1
@JayVyas NIO по умолчанию блокируется.
Я написал статью о самом быстром и самом медленном способах, которые я могу придумать, для использования IO и NIO в Java. Самое медленное, что я мог придумать, - это создание нового соединения каждый раз, но это все равно было 3500 сообщений / с с одним клиентом. vanilla-java.github.io/2018/08/28/Reducing-network-latency.h tml Я подозреваю, что ваши основные задержки не на сетевом уровне. Вы можете многое сделать, чтобы сделать этот код более эффективным, но я сомневаюсь, что это объясняет наблюдаемую вами медлительность. Вы пробовали профилировать свое приложение с помощью JMC?