У меня есть провайдер (A), который хочет отправлять нам данные через входящее TCP-соединение. К сожалению, служба-получатель (B) не может принимать входящие TCP-соединения. Также у него нет статического IP-адреса, еще одно требование.
Одним из способов решения этой проблемы является служба, которая соединяет входящий порт TCP A с другим портом TCP B, чтобы потребитель мог установить исходящее соединение с B.
Это не уникальная проблема [1] [2], а с socat я могу сделать что-то очень близкое к тому, что хочу:
socat -d -d -d -u TCP4-LISTEN:PORT-A,reuseaddr TCP4-LISTEN:PORT-B,reuseaddr
Однако при этом возникают следующие проблемы:
TCP4-LISTEN:PORT-B,reuseaddr,fork
, он может подключиться, но не получает данные.PORT-B
(преодолимо)Есть ли способ настроить команду таким образом, чтобы она стала «постоянной» и устойчивой к сбоям?
Важный вопрос: как A отреагирует на потерю соединения или на отказ в соединении? Все, что предполагает, что одно TCP-соединение будет работать вечно, будет хрупким; такова природа Интернета.
Как насчет настройки socat
как [x]inetd
служба?
Вы бы установили xinetd
для прослушивания в PORT-B, и запустить socat -u TCP4-LISTEN:PORT-A,reuseaddr STDIO
как только сторона B подключится.
xinetd
будет передавать входящий трафик со стороны B на стандартный ввод socat
, и поймать стандартный вывод socat
и передайте его стороне B.
Если B отключается, то socat
процессу можно дать закончиться; xinetd
начнет новый, как только B снова подключится. Пока B отключен, A будет получать сообщения об ошибке «соединение отклонено».
Однажды мне пришлось сделать нечто подобное на старой системе HP-UX.
Реальный мир запутан.
В реальном мире иногда TCP-соединения умирают, это может произойти, например, если перезагружается межсетевой экран с отслеживанием состояния или NAT, если соединение идет слишком долго без трафика, если базовое соединение слишком долго не работает.
Кроме того, иногда, когда соединения умирают, они умирают не симметрично. Если соединение, передающее много данных, умирает, вероятно, отправитель заметит, что оно не работает, задолго до того, как это сделает получатель. У этого есть пара побочных эффектов.
Кроме того, TCP-соединения представляют собой поток байтов, а НЕ поток сообщений, поэтому, когда ваше соединение умирает, вы можете получить частичное сообщение.
Конечный результат этого приводит меня к выводу, что надежное решение требует понимания протокола приложения, чтобы ваше решение могло его понять.