![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| LSD |
|
||||||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15719 Регистрация: 24.3.2004 Где: Dublin Репутация: 19 Всего: 538 |
Возникла у меня тут потребность посмотреть сколько времени занимает соединение с помощью сокета. Накидал тестик:
Сервер
Клиент
А дальше происходит нечто интерестное, после некоторго количества итераций (около 4000) происходит ошибка: ava.net.BindException: Address already in use: connect и если посмотреть открытые порты то видно куча открытых подключений открытых lsass.exe: netstat -anb
некоторое время (около минуты), эти подключения висят открытыми, а затем закрываются. Пробовал запускать тест по Linux, там все в порядке, никаких ошибок. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
||||||
|
|||||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
возможно, windows просто не успевает. Я где-то встречал тесты, показывающие, что линукс имеет преимущество перед виндоус главным образом в сокетных операциях. Этим линукс и хорош для серверных приложений.
Это сообщение отредактировал(а) COVD - 1.9.2005, 21:32 |
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: нет Всего: 134 |
Умора, у меня time_wait в линухе наоборот висит.
Сокет устанавливается в состояниее TIME_WAIT, для того чтобы на него не могли придти устаревшие пакеты, которые были посланы до того, как сокет закрылся. В частности об этом Стивенс подробно очень писал. вот здесь, к примеру, обсуждается, что такое TIME_WAIT. Хотя довольно непонятно, зачем это надо локальным соединениям. Это сообщение отредактировал(а) Mayk - 1.9.2005, 22:06 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| vzf |
|
|||
|
Unregistered |
понятно, что сокет не закрывают, ожидая, что кто-то ещё законнектится. Вопрос: есть ли какая-нибудь опция, чтобы время ожидание свести к минимуму (или вообще к 0) или это фантастика? Если кто подскажет, буду очень благодарен.
|
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15719 Регистрация: 24.3.2004 Где: Dublin Репутация: 19 Всего: 538 |
Хороший вопрос, мне было бы тоже весьма интерестно это узнать как это сделать под виндами. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
как написано выше, сокет перед удалением временно переводится в состояние ожидания, чтобы на него не пришли устаревшие пакеты. Не совсем ясно, но к новым коннектам это отношения вроде не имеет. Вообще не понятно, почему такой интерес к этому времени ожидания. Ну, удалится этот сокет со временем. Максимальное количество сокетов в системе примерно 65000. В приведенном выше тесте новые сокеты открываются без паузы, в цикле. Ситуация искусственная. Наверное, можно определить порог, максимальное число коннектов в единицу времени, при котором конкретный компьютер устойчиво открывает- закрывает новые соединения. Если этот порог не отвечает требованиям, то надо распараллеливать обработку. |
|||
|
||||
| Alone |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 11.5.2003 Где: Dnepropetrovsk, U A Репутация: нет Всего: 6 |
Может стоит поискать опцию похожую на SO_REUSEADDR?
цитата: "В некоторых случаях система не позволяет программе привязаться к только что освобожденному порту, пока не дождется подтверждения приема всех данных, передававшихся через соответствующий сокет. В таком случае можно использовать этот ключ" -------------------- |
|||
|
||||
| vzf |
|
|||
|
Unregistered |
[quote]Вообще не понятно, почему такой интерес к этому времени ожидания. Ну, удалится этот сокет со временем. Максимальное количество сокетов в системе примерно 65000.
У меня например клиент привязан к localhost на конкретный порт (так надо было), и после первого запуска бывает, что сокет на этот адрес находиться в TIME_WAIT, и снова клиент не запустить. Причем интересно, что если сервер не передает много данных клиенту, то такое случается редко, а если передает, то всегда. Точно, наверное, дело в пакетах. |
|||
|
||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 2 Всего: 118 |
Ну как сказать. А если тот же Томкэт надо перезапустить. А он при небольшом деплое стартует за секунды. И валиться при быстром перезапуске. Сам сталкивался.
|
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Сервер всегда слушает на конкретном порту X. При новом коннекте (accept) создается сокет, которому система назначает любой свободный порт Y, и клиент с ним работает в другом потоке. А сервер продолжает прослушивать порт X и готов принять новое соединение. Когда созданный сокет закрывается, то он еще некоторое время висит в системе на порту Y, пока не истечет TIME_WAIT. Если же открытие сокета (accept) и его закрытие делать в одном потоке (как в приведенном выше тесте), то наверное из-за этого и возникают проблемы с TIME_WAIT, потому что сервер не может перейти к прослушиванию порта X, пока не закроется созданный сокет. Но имеет ли практическое применение такая однопоточная схема обработки? Это сообщение отредактировал(а) COVD - 9.9.2005, 22:32 |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15719 Регистрация: 24.3.2004 Где: Dublin Репутация: 19 Всего: 538 |
Там используется много потоков, после accept запускается SocketListener, который и работает дальше с сокетом. Да это и не принципиально, даже если я в одном потоке открываю сокет и тут же его и закрываю, то это влияет только на то, как быстро я смогу выполнить accept для другого соединения. Потоки это внутренее дело приложения, не могут они влиять на системные вещи. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Да, я ошибся |
|||
|
||||
| vzf |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 203 Регистрация: 10.9.2005 Репутация: нет Всего: 5 |
Взял вчера да и открыл свою любимою книгу про TCP/IP протоколы. Там прочитал примерно следующее. Пара адресов используемых при соединении после его завершения не могут быть использованы системой в течении периода 2MSL(maximum segment lifetime). Это правило позволяет TCP-модулю в случае необходимости повторить последний сегмент ACK (если он потерялся в пути , то другая сторона после таймаута вышлет свой сегмент FIN). На стороне выполняющей активное закрытие будут в течении 2MSL ждать сегмент с FIN, остальные сегменты будут отбрасываться. Тем самым дается гарантия, что задержавшиеся сегменты от предыдущего воплощения соединения не будут спутаны с сегментами нового соединения.
В API сокетов можно указать опцию SO_REUSEADDR, которая позволит приложению назначить себе местный порт, когда он еще пребывает в состоянии TIME_WAIT. Однако протокол TCP не допускает, чтобы с участием такого порта было создано новое воплощение того соединения, которое находится в состоянии TIME_WAIT. Но нарушение спецификации протокола TCP позволяет клиенту и серверу постоянно использовать заново те же номера портов для последовательных перевоплощений одного и того же соединения, НО ЛИШЬ В ТОМ СЛУЧАЕ, ЕСЛИ АКТИВНОЕ ЗАКРЫТИЕ ПРОИЗВОДИТ СЕРВЕР. Вот так там бы ло написано, но все равно я так и не понял можно ли (и как) сделать это. --------------------
Java - Write Once, Test EveryWhere! |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15719 Регистрация: 24.3.2004 Где: Dublin Репутация: 19 Всего: 538 |
Надо попробовать.
-------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: нет Всего: 134 |
Статейка Описывает как в винде изменить время на TIME_WAIT. ----8<---- Change the TIME_WAIT Timeout to Increase Connections (Windows NT/2000/XP) This setting determines the length of time that a connection will stay in the TIME_WAIT state before being closed. The default is 240 seconds which on a busy server will limit the maximum connections to around 200/sec. Reducing this setting will increase the maximum connection limit. Download this tweak with Tweak Manager! This tweak can be easily applied using WinGuides Tweak Manager. Download a free trial now! Open your registry and find or create the key below. Create a new DWORD value, or modify the existing value, called "TcpTimedWaitDelay" and set it according to the value data below. Exit your registry, you may need to restart or log out of Windows for the change to take effect. Registry Editor Example | Name Type Data | | (Default) REG_SZ (value not set) | | TcpTimedWaitDelay REG_DWORD 0x0000001e (30) | - | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\P... | - Registry Settings System Key: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters] Value Name: TcpTimedWaitDelay Data Type: REG_DWORD (DWORD Value) Value Data: 30-300 seconds (decimal) Disclaimer: Modifying the registry can cause serious problems that may require you to reinstall your operating system. We cannot guarantee that problems resulting from modifications to the registry can be solved. Use the information provided at your own risk. Last Modified: June 18 ---->8----
ну REUSE можно попробовать поставить через Socket.setReuseAddress() и проверить. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Работа с сетью | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |