socket.accept () в python;Как настроить сторону клиента для порта подключения - PullRequest
0 голосов
/ 13 октября 2018

Вместо публикации сценария длиной в милю приведем короткий пример: я создаю соединение TCP / IP между двумя компьютерами, на каждом из которых запущен один из следующих сценариев:

сервер:

# server.py
import socket

s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))

s.listen(5)

while True:
    c, addr = s.accept()
    print 'Connection from', addr
    c.close()

Клиент:

#client.py
import socket

s = socket.socket()

host = socket.socket()
port = 1234

s.connect((host, port))
print s.recv(1024)

, который дает мне готовый вид:

Connection from ('19*.1**.0.**', 54451)
Connection from ('19*.1**.0.**', 54452)
Connection from ('19*.1**.0.**', 54453)
Connection from ('19*.1**.0.**', 54454)

Что контролирует создание номеров 54451-54454?Я понимаю что это такое;номер порта, назначенный для подключения на стороне клиента.Я просто не могу понять, как контролировать число или, по крайней мере, диапазон, в котором оно выдано.

Возможно ли это вообще?Любые предложения очень помогут.Заранее спасибо.

1 Ответ

0 голосов
/ 13 октября 2018

Как правило, ваша ОС или среда выполнения назначает идентификаторы портов, если вы сами этого не сделали.

В частности, 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-адрес, что полезно, если ваш хост является многодомным.)

...