Python сокет / проблема порта / вопрос - PullRequest
0 голосов
/ 03 апреля 2011

Я пишу 2 небольшие программы (сервер и клиент), и всякий раз, когда я запускаю обе программы, и когда клиент подключается к серверу, вывод сервера говорит о том, что я подключен к порту, к которому я не подключился код. Я связал сервер и клиентский сокет с локальным хостом и портом 8000, но каждый раз, когда клиент подключается к серверу, он говорит, что клиент подключен к порту 52304 или другому номеру, большему, чем 50000, не так ли хотя бы постоянный номер порта, даже если это не тот номер, к которому я его привязал? Кроме того, я знаю, что если я запускаю серверную программу более одного раза в одном и том же терминале, даже если я вышел из программы, порт все еще занят, поэтому я обычно запускаю сервер, выходу из системы и затем завершаю работу с терминалом, который обычно решает проблему. эта проблема. Это еще одно замечание, которое я должен сделать, когда я запускаю серверную программу во второй раз в том же терминале, она распознает, что я пытаюсь привязаться к порту 8000, и программа не запустится, а затем, когда она выберет какой-нибудь случайный порт.

Вот мой код сервера:


import socket
import os</p>

<pre><code>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind('', 8000)

s.listen(5)

while 1:
    client,addr = s.accept()
    print "Accepted a connection from: ", addr
    data = client.recv(1024)
    client.send("You said: " + data)

Ответы [ 3 ]

2 голосов
/ 04 апреля 2011

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

Пожалуйста, оставьте свой код клиента. Вопреки тому, что подразумевает ваш вопрос, я не думаю, что вы bind обращаетесь к порту на стороне клиента. Могу поспорить, что ты просто connect Инг. Теперь, в общем, это то, что вы должны делать. Таким образом, тот факт, что вы озадачены результатами, означает, что вы не совсем понимаете, что именно происходит. Результаты, которые вы видите, вполне ожидаемы и нормальны.

Вот объяснение того, что происходит:

TCP-соединение однозначно идентифицируется (глобально уникально, поскольку ни в одном другом TCP-соединении во всем мире не будет такого идентификатора (хотя это не совсем верно для NAT и частных IP-диапазонов)) этими 4 частями информация:

  1. ip клиента
  2. клиентский порт #
  3. ip сервера
  4. порт сервера #

Когда ваш сервер сообщает о соединении, он печатает первые два значения, потому что они возвращаются вызовом accept. Когда вы делаете вызов bind на сервере, вы указываете значения 3 и 4. ОС обычно выбирает значения 1 и 2 для клиента автоматически, когда он делает connect вызов.

Клиент обычно не привязывается к порту (хотя может). Обычно это позволяет ОС выбрать порт для него. Клиентская ОС выберет номер порта из списка неиспользуемых номеров портов. При вызове connect на стороне клиента вы указываете значения 3 и 4 (значения, указанные в вызове bind на стороне сервера). ОС должна автоматически назначить для вас значения клиента 1 и 2.

Думайте об этом, как адрес отправителя и получателя на конверте. Вызов accept на стороне сервера сообщает адрес отправителя, поскольку, вероятно, сервер уже знает свой собственный адрес. Клиент больше всего интересуется адресом получателя (адресом сервера) и позволяет клерку (ОС) просто вставить адрес возврата,

0 голосов
/ 04 апреля 2011

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

Так что вам не нужно беспокоиться о портах, если соединение установлено.

Но если вы хотите, чтобы сервер мог получать больше, одно соединение, посмотрите на это: Несколько одновременных сетевых подключений - сервер Telnet, Python

0 голосов
/ 04 апреля 2011

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

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

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