Каков наилучший способ использования метода Bind в TCP-соединении? - PullRequest
2 голосов
/ 27 марта 2019

У меня на одном компьютере работают 2 приложения, одно из которых выступает в качестве TCP-сервера, а другое - в качестве TCP-клиента.В этой машине у меня 2 сетевых интерфейса, поэтому обязательно указать, какой из них следует использовать для соединения TCP.Для этой цели я использовал метод Bind, потому что я знаю, что один из них - 192.168.1.x, а другой - 10.1.135.x, но я сомневаюсь: когда я ставлю сам IP машины, например, 192.168.1.195это не работает, но если я поставлю шлюз IP 192.168.1.1, он работает.Код, который не работает:

    tmpTcp := TTCPBlockSocket.Create;
    tmpTcp.Bind('192.168.1.195', '50000');
    tmpTcp.Connect('192.168.1.195', '50000');

Этот фрагмент кода, приведенный ниже, Работает

    tmpTcp := TTCPBlockSocket.Create;
    tmpTcp.Bind('192.168.1.1', '50000');
    tmpTcp.Connect('192.168.1.195', '50000');

Я видел описание метода Bind, но это не помогло. Можете ли выуказать направление по этому поводу?

Tks заранее

1 Ответ

4 голосов
/ 27 марта 2019

У меня на одном компьютере работают 2 приложения, одно из которых выступает в качестве TCP-сервера, а другое - в качестве TCP-клиента. В этой машине у меня 2 сетевых интерфейса, поэтому обязательно указать, какой из них следует использовать для TCP-соединения.

Нет, не обязательно привязывать один интерфейс к другому. Например, вы можете привязать сервер к обоим интерфейсам, привязав его к подстановочному знаку 0.0.0.0, тогда клиент может использовать любой интерфейс, который он хочет подключить к серверу. Или, поскольку клиент находится на том же компьютере, что и сервер, вы можете вместо этого связать сервер с 127.0.0.1, что позволит устанавливать соединения только с локального компьютера, а не из сети.

я сомневаюсь: когда я ставлю сам IP машины, например, 192.168.1.195, это не работает

Да, это работает, и это только способ привязки сокета к определенному интерфейсу в Windows (есть другие способы привязки к интерфейсам на * платформах Nix). Вы должны Bind() указать фактический IP-адрес, назначенный интерфейсу. Вы не можете связать с внешним IP-адресом, таким как IP-адрес маршрутизатора / шлюза.

но если я поставлю шлюз IP 192.168.1.1, он будет работать.

Нет, это не работает. Вы не можете Bind() использовать IP-адрес, который не принадлежит локальному компьютеру.

Не работает код

tmpTcp := TTCPBlockSocket.Create;
tmpTcp.Bind('192.168.1.195', '50000');
tmpTcp.Connect('192.168.1.195', '50000');

Сбой, потому что вы Bind() используете тот же IP / порт, к которому затем Connect(). НЕ ДЕЛАЙТЕ ЭТОГО.

Если не требуется из-за ограничений протокола / сети (ни один из которых не применяется в вашем случае), TCP-клиент НЕ должен связываться с конкретным портом, даже если он связывается с конкретным интерфейсом. Позвольте клиенту использовать временный порт, назначенный операционной системой, например:

tmpTcp := TTCPBlockSocket.Create;
tmpTcp.Bind('192.168.1.195', '0'); // <-- note the '0'!
tmpTcp.Connect('192.168.1.195', '50000');

Согласно документации :

Если значение порта равно «0», система выбирает себя и подключает неиспользуемый порт в диапазоне от 1024 до 4096 (это зависит от операционной системы!).

Или лучше, просто не Bind() клиент вообще, позвольте ОС выяснить это для вас во время Connect():

tmpTcp := TTCPBlockSocket.Create;
tmpTcp.Connect('192.168.1.195', '50000');

ОС будет неявно связывать клиента с соответствующим интерфейсом, который может достигать 192.168.1.195.

Этот кусок кода, ниже, Работает

tmpTcp := TTCPBlockSocket.Create;
tmpTcp.Bind('192.168.1.1', '50000');
tmpTcp.Connect('192.168.1.195', '50000');

Только потому, что Bind() действительно потерпит неудачу, поскольку IP-адрес недействителен для локальной машины, и тогда Connect() просто будет неявно привязываться к соответствующему локальному интерфейсу при необходимости.

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