Задержка нескольких соединений TCP с Java на ту же машину

Простая вещь сделать, когда Вы понимаете Вас просто, ввела неправильную строку, поражен Ctrl+C; если Вы хотите сохранить строку, но должны выполнить что-то еще сначала, начать новую строку с наклонной черты влево - \, то Ctrl+C. Строка останется в Вашей истории.

9
задан 11 revs 13 April 2017 в 12:13
поделиться

10 ответов

Я не нашел реального ответа из этого обсуждения. Лучшая теория, которую я придумал:

  1. Уровень TCP отправляет SYN на уровень MAC. Это происходит из нескольких потоков.
  2. Первый поток видит, что IP не имеет соответствия в таблице ARP, отправляет запрос ARP.
  3. Последующие потоки видят, что есть ожидающий запрос ARP, поэтому они полностью отбрасывают пакет. Такое поведение, вероятно, реализовано в ядре нескольких операционных систем!
  4. Ответ ARP возвращается, исходный запрос SYN от первого потока покидает машину, и устанавливается TCP-соединение.
  5. Уровень TCP ожидает 3 секунды, как указано в RFC 1122, затем повторяет попытку и завершается успешно.

Я попытался настроить тайм-аут в Windows 7 но не удалось. Если кто-нибудь сможет воспроизвести проблему и предложить обходной путь, я буду очень полезен. Кроме того, если у кого-то есть более подробная информация о том, почему именно это явление происходит только с несколькими потоками, было бы интересно услышать.

Я постараюсь принять этот ответ, так как не думаю, что какой-либо из ответов дает истинное объяснение (см. обсуждение мета ).

Если кто-нибудь сможет воспроизвести проблему и предложить обходной путь, я буду очень полезен. Кроме того, если у кого-то есть более подробная информация о том, почему именно это явление происходит только с несколькими потоками, было бы интересно услышать.

Я постараюсь принять этот ответ, так как не думаю, что какой-либо из ответов дает истинное объяснение (см. обсуждение мета ).

Если кто-нибудь сможет воспроизвести проблему и предложить обходной путь, я буду очень полезен. Кроме того, если у кого-то есть более подробная информация о том, почему именно это явление происходит только с несколькими потоками, было бы интересно услышать.

Я постараюсь принять этот ответ, так как не думаю, что какой-либо из ответов дает истинное объяснение (см. обсуждение мета ).

3
ответ дан 4 December 2019 в 15:21
поделиться

Похоже, вы используете одно базовое HTTP-соединение. Так что другой запрос может '

3
ответ дан 4 December 2019 в 15:21
поделиться

Если на одной из машин установлен Windows, я бы посмотрел на максимальное количество одновременных подключений на обеих. См.: http://www.speedguide.net/read_articles.php?id=1497

Я думаю, что в некоторых случаях это ограничение на уровне приложения, поэтому вам придется следовать руководству, чтобы поднять их. .

Кроме того, если это то, что происходит, вы должны увидеть что-то в журнале системных событий на машине-нарушителе.

1
ответ дан 4 December 2019 в 15:21
поделиться

I have seen similar behavior when I was getting DNS timeouts. To test this, you can either use the IP address directly or enter the IP address in your hosts file.

0
ответ дан 4 December 2019 в 15:21
поделиться

Помогает ли установка socket.setTcpNoDelay (true) ?

0
ответ дан 4 December 2019 в 15:21
поделиться

Пытались ли вы увидеть, какие системные вызовы выполняются при запуске вашего клиента с strace .

Это было очень полезно для меня в прошлом, при отладке некоторых загадочные проблемы с сетью.

0
ответ дан 4 December 2019 в 15:21
поделиться

Поскольку проблема не может быть воспроизведена, если вы не очистите связанный кэш ARP, как выглядит вся трассировка пакета с точки зрения синхронизации, с момента отправки запроса ARP до момента, когда 3 вторая задержка?

Что произойдет, если вы откроете соединение с двумя разными IP-адресами? Удастся ли первое подключение к обоим? Если это так, это должно исключить любые проблемы с JVM или библиотекой.

Первый SYN не может быть отправлен, пока не будет получен ответ ARP. Возможно, ОС или стек TCP использует тайм-аут вместо события для потоков, помимо первого, которые пытаются открыть соединение, когда связанный MAC-адрес неизвестен.

Представьте себе следующий сценарий:

  1. Поток №1 пытается для подключения, но SYN не может быть отправлен, потому что кеш ARP пуст, поэтому он ставит запрос ARP в очередь.
  2. Затем, Поток №2 (через №N) пытается подключиться. Он также не может отправить пакет SYN, потому что кеш ARP пуст. Однако на этот раз вместо отправки другого запроса ARP поток засыпает на 3 секунды, как сказано в RFC.
  3. Затем приходит ответ ARP. Поток №1 немедленно просыпается и отправляет SYN. ​​
  4. Поток №2 не ожидает запроса ARP; у него жестко запрограммированный 3-секундный сон. Таким образом, через 3 секунды он просыпается, находит нужную запись ARP и отправляет SYN. ​​
1
ответ дан 4 December 2019 в 15:21
поделиться

Вы поступаете правильно, уменьшая размер проблемного пространства. На первый взгляд, это невозможная проблема - что-то, что перемещается между IP-стеками, языками и машинами, но при этом не может произвольно воспроизводиться (например, я не могу воспроизвести ваш код в Windows или Linux).

Некоторые предложения, идущие сверху из стека вниз:

  • Код - вы говорите, что это происходит в .Net и Java. Существуют ли комбинации языка / компилятора, для которых этого не происходит? Я использовал ваш клиент для разговора с программой SocketTest из sourceforge, а также "nc" с идентичными результатами - без задержек. Точно так же JDK 1.5 и 1.6 не имели для меня никакого значения

    - Предположим, вы измеряете скорость, с которой клиент отправляет запросы, скажем, один каждые 500 мс. Проблема в репро?

  • Стек IP - возможно, что-то застревает в стеке при выходе. Я вижу, вы исключили Нэгла, но не забывайте глупостей вроде брандмауэров / таблиц IP. Мне было бы трудно поверить, что стек TCP в Win и Linux был таким замкнутым, но мало ли.

    - обработка интерфейса loopback может быть странной. Есть ли репро, когда вы используете настоящий IP машины? А как насчет сети (или, лучше, спина к спине с переходным кабелем к другой машине)?

  • NIC - если пакеты попадают на карты, рассмотрите особенности карт (разгрузка TCP или другая «специальная» обработка) или причуды в самих NIC. Получаете ли вы такие же результаты с сетевыми адаптерами других производителей?

3
ответ дан 4 December 2019 в 15:21
поделиться

Тот факт, что вы видите это на нескольких клиентах, с разными ОС и с разными средами приложений на (я полагаю) одной и той же ОС, является убедительным признаком того, что это проблема либо в сети, либо сервер, а не клиент. Это подтверждается вашим комментарием о том, что очистка таблицы ARP воспроизводит проблему.

Возможно, у вас есть две машины на коммутаторе с одинаковым MAC-адресом? (одним из которых, вероятно, будет маршрутизатор, который подделывает MAC-адрес.)

Или, что более вероятно, если я правильно помню ARP, две машины с одним и тем же жестко заданным IP-адресом. Когда клиент отправляет «who is IP 123.456.123.456», оба ответят, но на самом деле будет слушать только один.

Другая возможность (я видел, что это происходит в корпоративной среде) - это мошеннический DHCP-сервер,

1
ответ дан 4 December 2019 в 15:21
поделиться

Java client that uses HttpURLConnection to open concurrent connections to the same machine.

The same machine? What application does the clients accept? If you wrote that program by yourself, maybe you have to time how fast your server can accept clients. Maybe it is just a bad (or not fast working) written server application. The servercode looks like this, I think;

ServerSocket ss = ...;
while (acceptingMoreClients)
{
   Socket s = ss.accept();
   // On this moment the client is connected to the server, so start timing.
   long start = System.currentTimeMillis();
   ClientHandler handler = new ClientHandler(s);
   handler.start();

   // After "handler.start();" the handler thread is started,
   // So the next two commands will be very fast done.
   // That means the server is ready to accept a new client.
   // Stop timing.
   long stop = System.currentTimeMillis();
   System.out.println("Client accepted in " + (stop - start) + " millis");
}

If this result are bad, than you know where the problem is situated.
Я надеюсь, что это поможет вам приблизиться к решению.


Вопрос:

Для проведения теста вы используете IP-адрес, полученный от DHCP-сервера, или 127.0.0.1 Если это от DHCP-сервера, все идет через маршрутизатор / коммутатор / ... от вашей компании. Это может замедлить весь процесс.

В противном случае:

  • В Windows весь TCP-трафик (с локального хоста на локальный) будет перенаправлен на программный уровень системы (а не на аппаратный уровень), поэтому вы не может видеть TCP-трафик с Wireshark. Wireshark видит только трафик, который проходит на аппаратном уровне.
  • Linux: Wireshark может видеть только трафик на аппаратном уровне. Linux не перенаправляет на программный уровень. Это также причина, по которой возвращается InetAddress.getLocalhost (). GetAddress () 127.0.0.1 .

  • Поэтому, когда вы используете Windows, это нормально, что вы не видите SYN-пакет с Wireshark.

Martijn.

1
ответ дан 4 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: