Как правило, ваша ОС или среда выполнения назначает идентификаторы портов, если вы сами этого не сделали.
В частности, TCP имеет два порта на соединение: порт источника и порт назначения,иногда называют локальным и удаленным.Использование s.bind
устанавливает локальный порт на сервере без установки какого-либо удаленного порта (что имеет смысл: фактического соединения пока нет).Использование s.connect
устанавливает удаленный (целевой) порт на клиенте без установки какого-либо локального порта.
Когда ваш клиент отправляет запрос соединения насервер, вашему клиенту нужен локальный порт.Так как у него его еще нет, кое-что - ОС или система времени выполнения - выбирает его из пула доступных идентификаторов портов.Затем он привязывает этот идентификатор к локальной стороне клиентского сокета s
и отправляет запрос с (я предполагаю 192.168 RFC-1918 здесь пространство частных адресов):
<local-addr=192.168.xxx.xxx, local-port=54451, remote-addr=S, remote-port=1234>
(где S - этоIP-адрес сервера).
Сервер видит входящий запрос, создает новый сокет с:
<local-addr=S, local-port=1234, remote-addr=192.168.xxx.xxx, remote-port=54451>
, который, как вы можете видеть, является той же паройIPaddr + номера портов, только что поменялись местами.
Этот новый сокет - это то, что s.accept
возвращает на сервере, как c
.
Если вы хотите назначитьВаш собственный локальный порт на клиенте, вы также можете позвонить туда bind
, прежде чем звонить connect
:
s.bind((0, port))
(Ноль означает «неназначенный», поэтому локальный IP-адрес остается неустановленным. Вы можетезадайте конкретный IP-адрес, что полезно, если ваш хост является многодомным.)