Я разрабатываю приложение обратной оболочки в python, и сейчас я пытаюсь реализовать функцию автообнаружения. Он должен работать следующим образом:UDP широковещательная рассылка и автоматическое обнаружение сервера в python, сокет TCP недоступен
- Сервер передает IP-порт, на который он прослушивает подключения, и ждет клиента. Если клиент не пытается подключиться через несколько секунд, он снова транслирует (и повторяется до соединения).
- Клиент пытается получить широковещательную передачу сервера и подключается к рекламируемому IP/порту.
Радиопередача работает отлично, клиент получает IP/порт и успешно подключается, однако после того, как с помощью подсоединенных паров портов я получаю (на стороне сервера):
socket.error: [Errno 35] Resource temporarily unavailable
сервер код бокового теста:
sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sckt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sckt.settimeout(2)
sckt.bind(('', 9999))
sckt.listen(5)
broadcastSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadcastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
broadcastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
while True:
broadcastSocket.sendto(socket.gethostbyname(socket.getfqdn()) + ' ' + str(9999), ('<broadcast>', 8888))
try:
sock, address = sckt.accept()
break
except socket.timeout:
pass
broadcastSocket.close()
sckt.settimeout(None)
sock.send('test')
# if I add time.sleep(1) here, it works, but I don't get why
# would sock be unavailable at first, but available a second later
print sock.recv(1) # this is where it fails
# note that it also fails with any recv buffer size, for instance 1024
Почему бы мне не получить 1 байт данных, вы можете спросить. У меня есть алгоритм, который префикс сообщения с их длиной, и получатель читает этот префикс побайтовым образом до разделителя, вот почему. клиентского код на сторону теста:
broadcastSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadcastSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadcastSocket.settimeout(3)
broadcastSocket.bind(('', 8888))
while True:
try:
data = broadcastSocket.recv(1024)
break
except socket.timeout:
pass
broadcastSocket.close()
sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sckt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sckt.connect((str(data.split()[0]), int(data.split()[1])))
print sckt.recv(1024)
sckt.send('lel')
Если я опускаю все широковещательные и автообнаружению часть коды и просто вручную ввести IP/порт сервера print sock.recv(1)
не подведет. Любые подсказки о том, что может быть проблемой?
Он работает. Ваш код должен добавить, 'send' и' recv' вызовы, вызывающие ошибку – mementum
Я добавил несколько строк кода, который вызывает ошибку. –
Теперь ясно. В любом случае вы можете изменить заголовок, потому что ваша реальная проблема связана с сокет TCP. Что-то по строкам «TCP-сокет умирает до получения данных» – mementum