#c #windows #networking #client-server
#c #Windows #сеть #клиент-сервер
Вопрос:
У меня есть приложение, которое необходимо соединить с клиентом на удаленной машине. На сервере может быть запущено несколько экземпляров этого приложения, каждый из которых обслуживает другого клиента, вероятно, до 25-30 пар.
У каждой пары сервер-клиент должно быть два tcp-соединения. Серверное приложение имеет 2 процесса, и у каждого процесса есть свое собственное tcp-соединение с клиентом.
- Процесс A обменивается командами с клиентом
- Процесс B получает постоянный видеопоток от клиента.
Кроме того, существует другое tcp-соединение между каждой парой Процесс A / процесс B
Команды / данные будут поступать следующим образом:
Клиент <—> Процесс A <—> Процесс B
пока видео будет течь в этом направлении:
клиент -> Процесс B
Мне нужна помощь, чтобы определить, какой наилучший способ установить все tcp-соединения. Кто настраивает прослушиватели? как определить порты, которые будут использоваться? и т.д.
В настоящее время у меня есть единственный экземпляр процесса A, который взаимодействует как с процессом B, так и с клиентом, но все это выполняется на одном компьютере, поэтому я просто использую «localhost» в качестве имени моего хоста на данный момент. Я также жестко кодирую 2 порта, которые я использую, поэтому мне нужно изменить и это, когда у меня есть несколько экземпляров, чтобы каждый экземпляр использовал разные порты.
Как только процесс A устанавливает соединение с клиентом, ему необходимо запросить у клиента порт, чтобы процесс B мог установить другое соединение непосредственно с клиентом. Это хороший способ сделать это, или какой способ лучше? Как клиент может определить, какой порт доступен для использования?
Также была бы оценена любая помощь или указания о том, как назначить порты, чтобы это могло работать с несколькими экземплярами.
Спасибо, пожалуйста, задавайте любые вопросы обо всем, что непонятно.
РЕДАКТИРОВАТЬ: На самом деле процесс A и процесс B — это два разных приложения.
Ответ №1:
Я недостаточно знаю о приложении, поэтому, возможно, это можно еще больше упростить, но я бы сделал следующее:
-
Создайте один или два серверных процесса, прослушивающих известные порты (вероятно, вы могли бы сократить это до одного, но если вам нужно два, хорошо, я объясню, как это сделать).
-
Если вы можете свести это к одному серверному процессу, он может сам прослушивать оба порта. Используя
select
вызов, вы можете заставить его отслеживать активность в каждом открытом файловом дескрипторе. На самом деле, вот почему я думаю, что вы могли бы сделать все это с помощью одного процесса или небольшого пула из них. -
Попросите клиента подключиться к известному порту на сервере. Подключение сервера к клиенту вызовет проблемы при подключении к удаленным сетям. Вы всегда можете разместить сервер где-нибудь с переадресацией портов или в DMZ, но вы не можете настаивать на том, чтобы все ваши клиенты меняли свою сеть, чтобы удалить NAT, отключить брандмауэры или перенаправлять порты для вашего приложения.
-
Когда клиент подключается, если вам нужно несколько процессов, пусть серверы установят открытое соединение друг с другом перед разветвлением, чтобы вы могли подключить их, используя известный порт.
-
Если вам нужен отдельный процесс, используйте
fork
для разделения процессов. В дочернем процессе вы закрываете файловые дескрипторы, которые прослушивают известные порты. И в родительском процессе вы закрываете файловые дескрипторы, которые подключены к клиентам, в дополнение к файловым дескрипторам, которые подключены к другому серверному процессу.
Примечание: это из фоновой версии Linux, но я почти уверен, что все эти функции и методы будут работать в Windows. Я уверен, что кто-нибудь поправит меня, если я ошибаюсь. Я настоятельно рекомендую попробовать использовать select
, чтобы свести это к одному процессу, который значительно упростит ваше кодирование. Если вам нужно лучше использовать многопроцессорную систему, тогда используйте многопоточность или создайте пул процессов, которые компенсируют обработку соединений. Изучение того, как работают файловые дескрипторы после fork
, упростит ваше кодирование, если вам потребуется создать несколько процессов.
Комментарии:
1. Спасибо за ваши комментарии. На самом деле процессы A и B — это два разных приложения, поэтому родительского / дочернего процесса нет. Форк не используется.
2. вы говорите «Пусть клиент подключится к известному порту на сервере», как это будет работать, когда у меня запущено несколько экземпляров серверных приложений. Каждый экземпляр должен находиться на другом порту.
3. Если это два отдельных процесса, у вас должно быть по крайней мере два известных порта, процедуры A и B. Если вы не можете свести процесс B к одному процессу, который прослушивает и разветвляет дочерние процессы, то для каждого процесса B я бы попросил его связаться с процессом A с номером порта, который найден открытым. Процедура A может отправить этот номер порта клиенту для его второго подключения.
4. Чтобы получить открытый порт, вы можете предоставить процессу B начальный порт и в цикле заставить его попытаться связать / прослушать, а в случае сбоя вернуться к началу цикла и увеличить порт.