Ошибка 99 — Не удается назначить запрошенный адрес

#python #sockets #socket.io #udp #udpclient

Вопрос:

Я пытаюсь подключиться к IP-адресу для получения данных. IP-адрес принадлежит экземпляру AWS ec2, и мы открыли UDP-порт на сервере. Каждый раз, когда я пытаюсь привязать, я получаю эту ошибку [Errno 99] Cannot assign requested address

 UDP_IP = "XX.XXX.XX.XX"
UDP_PORT = YYY

sock = socket.socket(socket.AF_INET,  # Internet
                     socket.SOCK_DGRAM)  # UDP

sock.bind((UDP_IP, UDP_PORT)) # this is the line throwing the error

# sock.setblocking(0)
while True:
    data, address = sock.recvfrom(4096)
    print("received message:", data)
 

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

Ответ №1:

Как правило, sock.bind(('',port)) это все, что вам нужно для получения сообщений на порту. Это означает «прослушивание входящих пакетов, которые подключаются ко всем интерфейсам», Вы не даете представления о том, что означает «XX.XXX.XX.XX», но вам не нужно быть конкретным, если вы не хотите слушать только определенный интерфейс. Вы не привязываетесь при отправке в порт, вы просто sock.sendto(msg,(serverip,port)) . Хост, получающий пакет, также получает адрес, с которого он был отправлен, и может .sendto() использовать этот адрес для ответа.

Вот пример взаимодействия клиента и сервера:

server.py

 import socket

HOST = '' # receive on all interfaces
PORT = 5000

server = socket.socket(type=socket.SOCK_DGRAM)
server.bind((HOST,PORT))
while True:
    data,(ip,port) = server.recvfrom(4096)
    msg = data.decode()
    print(f'from {ip}:{port}> {msg}')
    if msg == 'quit': break # terminate server
    server.sendto(f'Response: <{msg}>'.encode(), (ip,port))
print('SERVER EXIT')
 

client.py

 import socket

SERVER = 'localhost' # or specific IP of host accessible by client
PORT = 5000

client = socket.socket(type=socket.SOCK_DGRAM)
while True:
    msg = input('Client> ')
    client.sendto(msg.encode(), (SERVER,PORT))
    if not msg or msg == 'quit': break # empty message to quit client only
    response,addr = client.recvfrom(4096)
    print(response.decode())
print('CLIENT EXIT')
 

Демо (клиент):

 C:> client
Client> test1
Response: <test1>
Client> test2
Response: <test2>
Client>                       # empty message only quits client
CLIENT EXIT

C:> client                   # 2nd client
Client> test3
Response: <test3>
Client> 你好!
Response: <你好!>
Client> quit                  # quit client and server
CLIENT EXIT
 

Демо (сервер):

 C:> server
from 127.0.0.1:49164> test1
from 127.0.0.1:49164> test2
from 127.0.0.1:49164>
from 127.0.0.1:49165> test3   # note client port change for 2nd client
from 127.0.0.1:49165> 你好!
from 127.0.0.1:49165> quit
SERVER EXIT
 

Комментарии:

1. «XX.XXX.XX.XX» — это эластичный ip-адрес, я просто не хочу его выдавать по соображениям безопасности, но это что-то вроде «34.xxx.xx.9». Существует устройство udplogger, настроенное для пересылки сообщений на этот конкретный IP-адрес и порт. Я получаю вышеуказанную ошибку, когда пытаюсь подключиться к IP и ПОРТУ, localhost работает нормально, для целей тестирования localhost работает нормально, проблема в удаленном устройстве.

2. @IsaacSekamatte Фактическое значение не имеет значения, только то, к чему оно относится. Опять же, вы не привязываетесь к удаленному IP-адресу. Вы привязываетесь только к локальному интерфейсному порту для получения сообщений. Для отправки на удаленный порт используйте .sendto(msg,(remoteip,port)) , привязка не требуется.