Подтвердить что ты не робот

Почему bind() используется в TCP? Почему он используется только на стороне сервера, а не на стороне клиента?

Я хотел узнать точную функцию bind() в TCP. Что означает "привязка" локального адреса к сокету? Если он назначает номер порта для сокета, то почему мы не используем его в клиенте? Я знаю, что порт назначается ОС автоматически на стороне клиента, но я не понимаю, как все это работает.

После bind() мы прослушиваем(). Как привязка связана с listen()? Будет ли listen() знать, что bind() был выполнен? Если да, то какие изменения связывают() так, чтобы он был известен? Я имею в виду, как справиться с возвратом нуля для успешного выполнения?

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

4b9b3361

Ответ 1

Он назначает "локальный" номер конечного порта.

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

Однако для клиентского сокета локальный адрес и порт обычно не имеют значения. Таким образом, вы не bind(). Если сервер ограничивает своих клиентов, возможно, иметь определенный номер порта или номер порта из заданного диапазона, вы также можете использовать bind() на стороне клиента.

С другой стороны, вы можете иметь возможность listen() в сокете, где вы не вызывали bind() (на самом деле я не уверен в этом, но это имеет смысл). В этом случае ваш серверный порт будет случайным, и серверный процесс будет передавать свой порт другим клиентом. Представьте себе протокол с двойным соединением, такой как FTP, где у вас есть управляющее соединение и соединение с данными. Порт, к которому подключается передача данных, является полностью произвольным, но должен быть передан другой стороне. Таким образом, используется "автоматически определенный порт".

Один пример в Python:

import socket
s = socket.socket() # create your socket
s.listen(10) # call listen without bind
s.getsockname() Which random port number did we get?
# here results in ('0.0.0.0', 61372)

s2 = socket.socket() # create client socket
s2.connect(('localhost', 61372)) # connect to the one above
s3, x = s.accept() # Python specific use; s3 is our connected socket on the server side
s2.getpeername()
# gives ('127.0.0.1', 61372)
s2.getsockname()
# gives ('127.0.0.1', 54663)
s3.getsockname()
# gives ('127.0.0.1', 61372), the same as s2.getpeername(), for symmetry
s3.getpeername()
#gives ('127.0.0.1', 54663), the same as s2.getsockname(), for symmetry
#test the connection
s2.send('hello')
print s3.recv(10)

Ответ 2

Он "связывает" сокет с адресом, иначе он не знает, какой адрес (пара ip-address/port) он должен прослушать.

И bind может использоваться и на стороне клиента. Один пример - на компьютере с несколькими сетевыми картами, подключенными к одной и той же сети, но клиент хочет, чтобы его видели только исходящие из одного определенного сетевого адреса.

Связывание используется не только для сокетов TCP, но также для сокетов UDP и других протоколов.

Ответ 3

bind() определяет локальный порт и адрес интерфейса для подключения. connect() имеет неявный bind("0.0.0.0", 0), если он не был выполнен ранее (при этом нуль принимается как "любое" ).

Для исходящих соединений это обычно приемлемо и предпочтительно. ОС просто привязывается к "всем интерфейсам" и выбирает какой-то высокосортный неиспользуемый порт. Вам нужно всего лишь привязать клиента, если сервер ожидает, что вы будете поступать из определенного порта или диапазона портов. Некоторые службы разрешают только соединения с номерами портов меньше 1024, которые могут быть привязаны только суперпользователем, хотя в наши дни это не означает, что все управляют своей собственной машиной.

Для входящих подключений вы должны привязываться к известному порту, чтобы клиенты знали, с кем вам связаться. Как только они это сделают, они предоставили серверу свой локальный адрес/порт, чтобы затем связь могла проходить в обоих направлениях. listen() будет работать только после вызова bind().

Все сокеты должны связываться, будь то UDP, TCP или другие. Это не всегда явно сделано.

Ответ 4

Я знаю, что это старый вопрос, но у меня есть новый ответ:)

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

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

Чтобы получить список ваших интерфейсов и ips, см. этот ответ.