Сокет UDP не может получать ответы, когда в Linux используется функция подключения - PullRequest
0 голосов
/ 19 января 2019

Я пишу UDP-сервер и клиент, используя Python. Код прост. Когда клиент udp отправляет данные на сервер, сервер отвечает клиенту на сообщение.

Код сервера выглядит следующим образом, имя файла «serverudp.py».

#!/usr/bin/env python

from socket import *
HOST = ''
PORT = 19998
s = socket(AF_INET,SOCK_DGRAM)
s.bind((HOST,PORT))
print '...waiting for message..'
while True:
    data,address = s.recvfrom(1024)
    print data,address
    s.sendto('this is the UDP server',address)
s.close()

Код клиента следующий, имя файла «clientudp.py»

#!/usr/bin/env python
from socket import *
HOST='10.0.0.12'
PORT=19998
addr=(HOST,PORT)
s = socket(AF_INET,SOCK_DGRAM)
s.connect(addr)
while True:
    message = raw_input('send message:>>')
    s.sendto(message, addr)
    data = s.recv(1024)
    print data
s.close()

Клиент не может получить никакого ответа. Однако, если я прокомментирую следующее подключить строку в коде клиента, она работает правильно.

#s.connect(addr)

Поскольку этот же клиентский код хорошо работает на другом компьютере Linux с линией connect , я хочу знать, в чем проблема с моим компьютером Linux? Есть ли какие-либо ограничения ядра Linux или сокета TCP / UDP с ним?

Надеюсь, ваши ответы, спасибо!

1 Ответ

0 голосов
/ 19 января 2019

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

Рассмотрим:

  1. Клиентподключается к 10.0.0.12:19998
  2. Клиент отправляет дейтаграмму на 10.0.0.12:19998 с одним из своих IP-адресов в качестве адреса источника.
  3. Сервер получает запрос, отправленный на 10.0.0.12:19998.
  4. Сервер формирует ответ на IP-адрес источника этой дейтаграммы и отправляет его на отправку.
  5. Сервер выбирает какой-либо IP-адрес источника, отличный от 10.0.0.12, поскольку он кажется "ближе" к месту назначения.IP-стек сервера не знает, что эта дейтаграмма в каком-то смысле является ответом на полученную дейтаграмму, и поэтому не имеет смысла устанавливать IP-адрес источника на 10.0.0.12.
  6. Клиент отклоняет ответ, поскольку он подключен к10.0.0.12 и ответ приходит с другого IP-адреса.

Короткая версия решения не предусматривает использование connect для UDP, если только сервер не гарантирует отправку датаграммы ответа сIP-адрес источника, соответствующий IP-адресу, на который клиент собирается connect.Ничто в вашей настройке не гарантирует этого.

Обычное решение - никогда не связывать UDP-сокет с подстановочным IP-адресом.Вместо этого привязайте сокет к определенному IP-адресу, который сервер будет использовать для связи со своими клиентами.

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