#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))
, привязка не требуется.