Воспроизвести задержку записи-записи-чтения с сокетами Java
Я читал, что комбинация из трех вещей вызывает что-то вроде задержки 200 мс с TCP: алгоритм Nagle, отложенное подтверждение и комбинация "запись-запись-чтение". Однако я не могу воспроизвести эту задержку с помощью сокетов Java, и поэтому я не уверен, правильно ли я понял.
Я запускаю тест на Windows 7 с Java 7 с двумя потоками, используя сокеты по адресу обратной связи. Я не трогал опцию tcpNoDelay ни на одном сокете (по умолчанию false) и не играл с настройками TCP в ОС. Основной кусок кода в клиенте, как показано ниже. Сервер отвечает байтом после каждых двух байтов, которые он получает от клиента.
for (int i = 0; i < 100; i++) {
client.getOutputStream().write(1);
client.getOutputStream().write(2);
System.out.println(client.getInputStream().read());
}
Я не вижу никакой задержки. Почему бы и нет?
1 ответ
Я полагаю, вы видите задержку подтверждения. Вы пишете 4 и 4 байта в сокет. Стек TCP сервера получает сегмент (который, вероятно, содержит как минимум 4 байта от целого числа) и пробуждает поток приложения сервера. Этот поток записывает байт обратно в поток, и этот байт отправляется клиенту в пределах сегмента ACK. Т.е. стек TCP дает возможность приложению немедленно отправить ответ. Так что вы не видите задержки. Вы можете написать дамп трафика, а также провести эксперимент между двумя компьютерами, чтобы увидеть, что на самом деле происходит.