Задать вопрос
DmitryKoterov
@DmitryKoterov

TCP-прокси, устойчивый к разрывам связи (с автоматическими реконнектами)

Предположим, есть сервер и некоторый клиент. Клиент соединяется с сервером по TCP. При этом клиент очень не любит, когда рвется связь: в силу своего несовершенства он считает, что соединение, однажды установившись, никогда уже не рвется, а если оно все же порвется, то, считайте, он умирает, и приходится всю работу делать заново.

Нет ли какой-то готовой утилиты, которая организует «логически устойчивое к разрывам связи» псевдосоединение между клиентом и сервером? Вот как это могло бы работать:

                                             |
                                             |
                                             |
КЛИЕНТ ----> localhost:1234                  |                 server:1234  -----> СЕРВЕР
                 демонК  <=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+> демонС
                           если здесь рвется, то демон утилиты
                           на клиенте реконнектится к демону
                           утилиты на сервере, но, что важно, при 
                           этом КЛИЕНТ не считает, что соединение
                           с СЕРВЕРом было разорвано, т.к. КЛИЕНТ
                           соединен с демоном на локалхосте (а
                           СЕРВЕР, соответственно, тоже с демоном
                           на его хосте).


Т.е. идея в том, что даже если связь порвалась на день (выключили и заменили роутер, поменяли провайдера — вообще все, что угодно), КЛИЕНТ все равно продолжает считать, что он соединен с СЕРВЕРом, и никакого дисконнекта не было (но просто соединение вдруг стало очень-очень тормозным — пропускает 1 пакет в день). С локалхостом-то соединение никогда не рвется…

P.S.
Просьба не предлагать всякие TCP keep-alive, тайм-ауты на уровне TCP и прочую дребедень — решение тут явно должно быть на уровне более высокого уровня, чем TCP (т.к. заставить TCP-соединение не разрываться в случае, например, физической замены роутера или переезда к другому интернет-оператору невозможно). Также нет возможности делать доработки в клиенте и сервере.
  • Вопрос задан
  • 5370 просмотров
Подписаться 2 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 5
@rPman
Просьба не предлагать всякие TCP keep-alive, тайм-ауты на уровне TCP и прочую дребедень — решение тут явно должно быть на уровне более высокого уровня, чем TCP (т.к. заставить TCP-соединение не разрываться в случае, например, физической замены роутера или переезда к другому интернет-оператору невозможно). Также нет возможности делать доработки в клиенте и сервере.
Как раз тут может помочь поднятый vpn сервер на server и клиент на client (или наоборот, не принципиально), соединение устанавливать соответственно уже в этой локальной сети. По крайней мере кратковременные разрывы связи (на сервере менял таблицу маршрутизации, openvpn переподключился, соединения не разорвались), но вот в долгосрочной перспективе я просто хз, какие еще факторы могут помешать.
Ответ написан
eigrad
@eigrad
Python-разработчик / Linux-админ
Единственный выход — написать самим. Логика восстановления подключения к серверу это дело уникальное. А если по факту нет никакого соединения то лучше было просто UDP использовать. Ну да и прокси написать в этом случае совсем не сложно.
Ответ написан
К сожалению, не все так просто, как кажется. В произвольном случае для произвольных прикладных протоколов эта задачка надежно не решается. Предположим, я реализую подобный прокси. Разрыв TCP-соединения произошел на некоей операции send(). Как я могу узнать, надо ли мне повторить отправку тех данных, которые были в этой send() или нет? Т.е. здесь действительно лучше использовать, например, UDP и поверх UDP писать какой-то свой транспорт, который будет устойчив к длительным разрывам связи.
Ответ написан
@Hint
А вы уверены. что сервер и клиент не обмениваются ping-пакетами? Т. е. клиент (сервер) шлет пакет серверу (клиенту) и, если не получает ответ в течение заданного интервала, рвет соединение.
Ответ написан
pietrovich
@pietrovich
Попробуйте stunnel, он кажется, вполне подойдет. только вот не помню. можно ли на нем поднять нешифрованный канал. Ну и, если нет возможности доставлять софт на сервер, прийдется перед сервером еще одну машину ставить. А так, вроде, должно помочь.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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