|
|
|
Netty
|
|||
|---|---|---|---|
|
#18+
Пишу сервер на netty и клиента для него. Возникли проблемы следующего характера: 1. Обрыв связи у клиента (выключил интернет) не приводит к удалению канала. 2. Отправляю сообщение через открытый канал. У клиента произошел обрыв связи. Сообщение не доставляется до клиента. После восстановления соединения. Как сделать автоудаление канала при обрыве связи с клиентом (какой-нибудь таймаут установить)? Как сделать повторную отправку сообщения до клиента после восстановления соединения (в случае, если таймаут из вопроса выше не истек)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2016, 09:11 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
1. Это не нетти, это уже TCP. При внезапном исчезновении удаленного клиента соединение сразу не рвется. Используйте SO_KEEPALIVE, самопальные пинги в составе протокола, или играйтесь с таймаутами TCP соединения. 2. Речь точно о голом нетти? Там вроде нет автоматического реконнекта. один канал = одно соединение, соединение умерло = канал закрыт и больше непригоден. Реконнект и повторную отправку надо писать руками. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2016, 14:03 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
scf1. Это не нетти, это уже TCP. При внезапном исчезновении удаленного клиента соединение сразу не рвется. Используйте SO_KEEPALIVE, самопальные пинги в составе протокола, или играйтесь с таймаутами TCP соединения. 2. Речь точно о голом нетти? Там вроде нет автоматического реконнекта. один канал = одно соединение, соединение умерло = канал закрыт и больше непригоден. Реконнект и повторную отправку надо писать руками. 1. Вот я и не могу найти информацию о том, как в Netty управлять таймаутами TCP. SO_KEEPALIVE - рвет соединение, но для этого минут 10 надо (читал, что от ОС зависит). 2. соединение умерло != канал закрыт (по крайней мере с теми настройками, которые у меня прописаны - SO_KEEPALIVE и SO_BACKLOG). Он открыт и в него можно писать. Никаких исключений не будет (пока с параметром SO_KEEPALIVE не вылетет исключение Connection timeout. Опять же, через большой промежуток времени). Реконнект и повторную отправку - с радостью сам напишу. Главное, чтобы канал рвался предсказуемо (либо моментально, либо по таймауту, заданному мной). Какой-то TCP не TCP получается. Не гарантирована доставка данных в моем случае. Хотелось бы прозрачности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2016, 18:52 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
Еще есть такая весчь. Немного прозрачнее становится разрыв соединения - например, если я 20 сек не прочитаю ни одного сообщения из канала - разрываю канал. Но, опять же, за эти 20 секунд я сам же запишу кучу сообщений в канал, не связанный с клиентом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2016, 18:57 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
"TCP гарантирует доставку" - это правда, но не вся. Говоря точнее: - TCP гарантирует, что получатель получит отправленные данные в нужном порядке и без дубликатов - если метод send() успешно завершен, это означает, что данные были переданы, но получатель может как получить их, так и НЕ получить. Если требуется гарантия, что получатель получил и обработал данные, он должен вернуть ответ. - TCP соединение считается живым, пока удаленная сторона не пришлет явно RST пакет либо пока локальная сторона не закроет соединение (вручную либо по одному из таймаутов) Т.е. поверх TCP можно реализовать три разных гарантии доставки: - at most once. Т.е. отправитель посылает данные в сокет и забывает о них. при реконнекте данные теряются. Т.е. получатель получит данные не больше одного раза - at least once. Отправитель посылает данные в сокет, но не удаляет их у себя, пока получатель не подтвердит получание. В случае реконнекта неподтвержденные данные отправляются повторно. Т.е. получатель получит все данные, но возможны дубликаты - exactly once. К каждому пакету данных прикрепляется уникальный идентификатор, и получатель хранит идентификаторы полученных пакетов, отбрасывая дубликаты. Примерно так :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2016, 21:25 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
В общем, подумайте над вопросами: - какая гарантия доставки вам нужна? - что такое для вас "обрыв связи"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2016, 21:31 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
Тут прочитал, что, TCP требует подтверждения доставки данных до получателя (после получения пакета данных на сервер отправляется ACK с номером подтверждения и WIN - размером окна). Если сервер отправляет данные, а клиент отключен, то ACK не должен приходить. Netty, я так понял, это дело игнорирует. Как-нибудь бы вытянуть информацию, что пакет не был получен без лишних пингов клиента. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2016, 10:44 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
TCP доставку не гарантирует. Эти все сказки для маленьких и для заказчиков. Есть некоторые случаи, когда действительно мы можете быть уверены, что доставка произошла. По большому счету, такой случай 1 - когда вы получили ответ. Плюс к этому, когда говорят "TCP обеспечивает сохранение последовательности данных", то предполагается это сохранение в рамках одного tcp-подключения. Если у вас есть 2подключения, то между ними порядка нет. В линукс tcp keep_alive стоит 7200, по крайней мере в убунту. В винде вроде 4 часа. Его можно поменять, подкрутив /proc/sys/net/ipv4/tcp_keepalive_* но это отразится на всей ОС. И работает оно как-то странно. Я пробовал уменьшать tcp_keepalive_time, и смотрел шарком что происходит. Так линукс почему-то не выдерживал заданное tcp_keepalive_probes. Но вцелом механизм работает так: через tcp_keepalive_time секунд посылается пакет, и если ответа нету, то считается что это обрыв связи, и тогда ОС возвращает select-у соответствующее событие. Насчет пункта 2. Обрыв связи может быть 2 типов: когда клиент его заметил, или когда клиент его не заметил. Карточки с поддержкой MII видят, когда из них выдергиваешь шнурок. Если у клиента такая сетевушка, то при выдергивании шнурка это видит карточка, она информирует ОС об обрыве, ОС закрывает соединение и клиент уже не получит ничего по этому подключению. Если у клиента не такая сетевушка, или выдергивание произошло за пределами свитча, то карточка клиента не может это увидеть, тогда обрыва не будет, и в этом случае (если на сервер тоже не увидит обрыва) сервер начинает предпринимать попытки по пересылки неподтвержденных данных. Делает он это, увеличивая в 2 раза (ну или не в 2) период между попытками посылок. В некоторых реализациях период увеличивается вплоть до какого-то порогового значения, которое я не помню чему равно по умолчанию. Тут я не помню конкретных величин, но вы можете считать, что там интервалы в итоге могут быть довольно большими. То есть, после того как связь восстановилась (и если сокеты по сторонам не оборвались) - надо подождать пока ос сделает повторную посылку. Ждать может понадобится долго, десятки минут и даже несколько часов на некоторых реализациях tcp. Это плохо в играх типа slither, но хорошо когда тянешь большие файлы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2016, 02:16 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
Alex_kip Тут прочитал, что, TCP требует подтверждения доставки данных до получателя (после получения пакета данных на сервер отправляется ACK с номером подтверждения и WIN - размером окна).Работая с (вариантом) API Беркли-сокетов не надо читать информацию об устройстве IP-стека. Если читаете - чётко отделяйте одно от другого.Если сервер отправляет данные, а клиент отключен, то ACK не должен приходить. Netty, я так понял, это дело игнорирует.Приложение не может игнорировать то, чего оно никогда не получает.Как-нибудь бы вытянуть информацию, что пакет не был получен без лишних пингов клиента.TCP строится поверх IP-сети. IP-сеть является сетью с негарантированной доставкой, поэтому TCP реализует надёжную доставку путём ожидания подтверждений и перепосылок. Если механизм ожиданий для вас слишком медленно - подтверждайте доставку каждой значимой порции данных на прикладном уровне. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2016, 08:00 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
тцп как минимум, гарантирует информирование если доставки не произошло. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2016, 15:01 |
|
||
|
Netty
|
|||
|---|---|---|---|
|
#18+
Всем спасибо. Буду использовать ReadTimeout, хранить все отправленные сообщения, пока не получу сообщение от клиента об успешной доставке, либо по истечении ReadTimeout. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2016, 18:59 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=93&tid=2123906]: |
0ms |
get settings: |
10ms |
get forum list: |
21ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
48ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
2ms |
| others: | 235ms |
| total: | 404ms |

| 0 / 0 |
