Может ли tcp-клиент использовать один и тот же порт для другого Сервера? - PullRequest
0 голосов
/ 19 февраля 2019

Я хочу написать tcp сервер и клиентское приложение, которое имеет несколько разных соединений друг с другом, где клиент использует один и тот же номер порта.

Насколько я понимаю, на сервере есть порт слушателя, и когда клиент вызывает его, я получаю новый сокет для этого нового соединения на стороне сервера, когда я вызываю

accept();

Правильно?Поэтому на стороне сервера я могу идентифицировать свое соединение с этим новым сокетом и отправлять данные через него.

Теперь у меня проблема с клиентской стороной.Там я получаю свой сокет, когда я звоню

socket(AF_INET, SOCK_STREAM, 0) 

, поэтому у меня есть только один сокет.В

connect() 

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

Но как теперь узнать в клиенте, с какого логического соединения я получаю свои данные, или как я могу отправить его, когда 2 логических соединения используют один и тот же локальный порт на клиенте?На сервере у меня есть 2 сокета, когда у меня есть 2 принятых вызова, но как насчет стороны клиента?Для отправки и получения у меня есть только один дескриптор сокета?

Или мне нужно вызывать socket () для каждого логического соединения на клиенте?

Ответы [ 4 ]

0 голосов
/ 20 февраля 2019

Я не буду говорить о конкретном языке программирования, а дам общий ответ, который применим для всех:

В сети вам важен сокет (IP + порт), который должен быть уникальным, независимо от того,это сокет сервер / клиент или сокет UDP / TCP.

Для серверных сокетов вы должны назначить порт.Для клиентских сокетов обычно вы специально не назначаете порт, но он будет назначен операционной системой автоматически.Однако вы все равно можете назначить порт клиентскому сокету вручную (например, если некоторые номера портов заблокированы брандмауэром)

В процессе сервера: вы можете получить информацию о сокете сервераи информация о подключенном клиентском сокете

В процессе клиента: вы можете получить информацию о клиентском сокете и информацию о сокете (к которому хотите подключиться) (конечно, вы должны знать серверИнформация о сокете ранее, иначе как вы будете подключаться к нему).

Вы можете отправлять / получать из / в клиентские сокеты.После того, как сервер получает подключенный клиентский сокет, он может отправлять / получать через него.То же самое для клиентской стороны, которую он может отправлять / получать через свой сокет.

0 голосов
/ 19 февраля 2019

Абстракция "сокета" - неудачный пережиток прошлого дизайна сетевого стека.Он смешивает два разных вида объектов.

A прослушивающий сокет на сервере имеет порт и, возможно, IP-адрес локального интерфейса.Однако это также может быть 0.0.0.0 при прослушивании на всех интерфейсах.

подключенный сокет связан с TCP-соединением и поэтому имеет 4 параметра: {local IP, local port, remote IP, remote port}.

Теперь на стороне клиента вам, как правило, нет дела до локального IP-адреса или локального порта, поэтому они назначаются локально на connect.И да, эти локальные параметры могут фактически использоваться для нескольких соединений.Только 4-кортеж из {local IP, local port, remote IP, remote port} должен быть уникальным.ОС сопоставит этот уникальный кортеж с вашим SOCKET.

Но так как вам нужен новый 4-кортеж для каждого соединения, из этого также следует, что вам нужен новый SOCKET с обеих сторон для каждого соединения,на клиенте и сервере.

0 голосов
/ 19 февраля 2019

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

Нет.Сокет TCP можно использовать только один раз.Когда его соединение завершено или даже если connect() просто не может установить соединение, вы должны закрыть сокет и создать новое, если вы хотите установить новое соединение.

Но как можноТеперь я вижу в клиенте, от какого логического соединения я получаю свои данные или как я могу отправить их, когда 2 логических соединения используют один и тот же локальный порт на клиенте?

Каждое TCP-соединение будет иметь свой собственный уникальныйгнездо для него выделено.Вы несете ответственность за их отслеживание.

На стороне сервера у меня есть 2 сокета, когда у меня есть 2 принятых вызова, но как на стороне клиента?

Точно так жеэто происходит и на стороне клиента.Вам нужно создать и подключить отдельный сокет для каждого соединения TCP, которое вы делаете.Итак, у вас будет новая пара вызовов socket() / connect() для каждого соединения.

Для отправки и получения у меня есть только один дескриптор сокета?

Нет, у вас будет отдельный сокет для каждого соединения, как на стороне сервера.

Или мне нужно вызывать socket () для каждого логического соединения на клиенте?

Да, и connect() тоже.

0 голосов
/ 19 февраля 2019

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

Нет.Сокет - это комбинация IP-адреса и номера порта.

Или мне нужно вызывать socket () для каждого логического соединения на клиенте?

Да.

  • Мне кажется, что ваша путаница возникает из-за того, что вы думаете, например, что определенный порт используется для SMTP-соединений, а определенный порт используется для HTTP-соединений.

    Хорошо,один только этот порт НЕ определяет для вас сокет к серверу.IP-адрес сервера меняется.

    В качестве примера рассмотрим следующий сценарий:

  1. Требуется подключение кStackoverflow:

    Ваш ПК - IP1 + порт 50500 ——– Stackoverflow IP2 + порт 80 (стандартный httpпорт)

    Это комбинация IP1 + 50500 = сокет на клиентском компьютере и IP2 + порт 80 = сокет назначения на сервере Stackoverflow.

  2. Теперь вы хотите подключиться к gnu.org:

    вашему ПК - IP1 + порт 50501 ——–gnu.org IP3 + порт 80 (стандартный http-порт)

    комбинация IP1 + 50501 = сокет на клиентском компьютере и IP3 + порт 80 = целевой сокет на сервере gnu.org.

Лучше проверить Сетевое программирование Beej Узнать больше.Это необходимо прочитать всем, кто работает с сокетами.

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