Как подключиться к определенному компьютеру, который имеет тот же внешний IP-адрес, что и другой? - PullRequest
0 голосов
/ 31 декабря 2018

Представьте себе следующую ситуацию с приложением удаленного доступа.

У меня есть два приложения «сервер-клиент» и одно приложение только для сервера (используется динамический DNS).

Когда я запускаю(1) Приложение «сервер-клиент», оно немедленно подключается к серверу и отображает его идентификатор / пароль / IP / порт в ListView, поэтому, когда я запускаю свое (2) приложение «сервер-клиент» и нажимаючерез каждый элемент ID / пароль / IP / порт на сервере ListView и приносит мне IP / порт относительно идентификатора / пароля.

Проблема заключается в том, что все эти приложения используют один и тот же внешний IP / порт, поэтомумое приложение не знает, к какому компьютеру подключаться.

Я уже разместил этот вопрос здесь, но в нем не было деталей, поэтому он был удален.Я публикую это снова, и я также предоставлю некоторый код.

Сначала я хотел, чтобы мне понадобилась служба DNS для каждого сервера-клиента, но это было слишком грязно и, вероятно, не помогло бы мне (ясобирался попытаться использовать компоненты IndyDNSServer и IndyDNSResolver).

После того, как я впервые разместил здесь мою проблему, пользователь сказал мне попробовать и использовать свойство TCustomWinSocket

Data ->

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/ScktComp_TCustomWinSocket_Data.html

Но я ничего не мог с этим поделать.

//This block here passes the IP/Port configuration to the other 
application socket (ClientS stands for ClientSocket[Number]).

ClientS2.Host := ClientS1.Host;
ClientS2.Port := ClientS1.Port;
ClientS3.Host := ClientS1.Host;
ClientS3.Port := ClientS1.Port;
ClientS4.Host := ClientS1.Host;
ClientS4.Port := ClientS1.Port;
ClientS5.Host := ClientS1.Host;
ClientS5.Port := ClientS1.Port;
ClientS6.Host := ClientS1.Host;
ClientS6.Port := ClientS1.Port;

MyFirstBmp := TMemoryStream.Create;
MySecondBmp := TMemoryStream.Create;
MyCompareBmp := TMemoryStream.Create;
PackStream := TMemoryStream.Create;
iSendCount := 0;
StatusBar1.Panels.Items[1].Text := 'Connected';
Timer2.Enabled := true;
BitBtn1.Enabled := false;
edtIPAddr.Enabled := false;
edtPort.Enabled := false;
edtPassword.Enabled := false;
edtName.Enabled := false;
frmCConectaNovaTela.bbtConecta.Enabled;

Sleep(1000);
Socket.SendText('<|MAIN|>');  // This text makes it so that the Main 
thread on the server application be created.

Я пытаюсь найти способ подключения моего приложения кконкретный компьютер, который имеет тот же внешний IP-адрес, что и другие компьютеры в той же сети, которые также используют мое приложение и имеют те же порты прослушивания на своих серверных сокетах.

Одним словом, у меня было бы что-то вроде ...

CS1.Host := '188.156.124.111';
CS1.Port := '32500';
CS1.Property := 'ThirdParameterToMakeADistinctConnection';

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Как я уже говорил, вы не можете использовать только один IP-адрес для идентификации конкретных сторон.Это просто недостаточно уникально.

Вы можете использовать свойство TCustomWinSocket.Data для отслеживания любых пользовательских данных, которые вы хотите.Например, когда клиент входит на ваш сервер, вы можете сохранить его общедоступный IP-адрес / порт для входящих подключений, его уникальный идентификатор (имя пользователя и т. Д.) И т. Д.

Когда клиент хочет отправитьсообщение другому клиенту, он может попросить сервер переслать сообщение на нужный идентификатор.Сервер может найти идентификатор в своем списке клиентов, а затем ретранслировать сообщение, если оно найдено.

Если у вас есть устройства, которые находятся за маршрутизатором, для создания входящего соединения с конкретным устройством из внешней сети.маршрутизатор должен иметь включенную переадресацию порта , где он открывает открытый порт, который перенаправляет весь полученный трафик на IP / порт частной локальной сети устройства.

Для одноранговых соединений клиент1 должен отправить сообщение клиенту 2, попросив его открыть прослушивающий порт, а затем клиент 2 должен ответить с публичным IP / портом, к которому затем может подключиться клиент 1.

Если клиент 2 находится за маршрутизатором,он должен открыть прослушивающий порт локально, как обычно, но затем ответить соответствующим IP-адресом / портом общего доступа, который открыт на маршрутизаторе.Он может использовать uPNP, чтобы попросить маршрутизатор динамически открыть порт пересылки (если маршрутизатор не поддерживает uPNP, порт переадресации должен быть предварительно статически настроен администратором маршрутизатора).

Если соединение не удается, получитеклиенты меняются ролями, где клиент 2 затем просит клиента 1 открыть порт прослушивания, к которому должен подключиться клиент 2.

0 голосов
/ 31 декабря 2018

Если я правильно понимаю вашу проблему, вам нужен NAT.

Это очень упрощенное и неполное объяснение.Для простоты я пытаюсь объяснить это только через порт TCP.

В вашей частной сети есть два компьютера, A (192.168.0.100) и B (192.168.0.200).Оба имеют один и тот же публичный адрес за маршрутизатором или тому подобное, в вашем примере 188.156.124.111.

Теперь вам нужно создать правила NAT на вашем маршрутизаторе.Примерно так:

  • Внешний порт 32500 для внутреннего порта 32500 на A (192.168.0.100)
  • Внешний порт 32501 на внутренний порт 32500 на B (192.168.0.200)

Теперь ваш клиент может установить соединение с A через порт 32500 и с B через порт 32501. Серверные приложения все еще прослушивают 32500.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...