Mamy istniejące oprogramowanie, które okresowo nadaje pakiety UDP do określonego portu (7125) w lokalnej podsieci (x.x.x.255). Mamy oprogramowanie monitorujące działające na HP-UX (11.11), które może odbierać te pakiety bez problemu. Jednak po przeniesieniu oprogramowania monitorującego na Linuksa (RHEL 6.1) stwierdziliśmy, że nie otrzymuje pakietów emisji. tcpdump pokazuje pakiety przychodzące na hosta Linux, ale jądro nie wysyła ich do naszego oprogramowania.Odbieranie pakietów emisji UDP w systemie Linux
Używam kilku skryptów w języku Python 2.x, które naśladują wywołania interfejsu API gniazda używane przez oprogramowanie monitorujące do testowania różnych scenariuszy. Jądro Linuksa przekazuje pakiety do oprogramowania odbiornika, jeśli nadawca używa unicast (10.1.0.5), ale nie nadaje (10.1.0.255). Przez kilka dni szukałem w internecie i nie znalazłem nikogo z tym samym problemem. Jakieś pomysły?
receiver.py
from __future__ import print_function
import socket
localHost = ''
localPort = 7125
remoteHost = '10.1.0.5'
remotePort = 19100
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((localHost, localPort))
s.connect((remoteHost, remotePort))
print('Listening on {0}:{1} for traffic from {2}:{3}'.format(localHost, localPort, remoteHost, remotePort))
data = s.recv(1024)
print('Received: {0}'.format(data))
s.close()
sender.py
from __future__ import print_function
import socket
import time
localHost = ''
localPort = 19100
remoteHost = '10.1.0.255'
remotePort = 7125
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((localHost, localPort))
s.connect((remoteHost, remotePort))
data = 'sending this from {0}:{1} to {2}:{3}'.format(localHost, localPort, remoteHost, remotePort)
print(data)
print('2')
time.sleep(1)
print('1')
time.sleep(1)
s.send(data)
print('sent at {0}'.format(time.ctime()))
s.close()
Czy Twój odbiornik nie musi "bindować" do adresu rozgłoszeniowego lub "INADDR_BROADCAST" (255.255.255.255, "INADDR_ANY" transmisji)? Oznacza to, że oprócz ustawiania opcji 'SO_BROADCAST' (po obu stronach), tak jak już to robisz. Czy sprawdzasz kody błędów/powrotu wszystkich tych wywołań systemu gniazd? –
@MatthewHall aha, wiązanie z adresem broadcast działa! Domyślam się, że to oznacza, że Linux wybiera między emisją jednostkową a emisją? Jesteśmy w stanie powiązać "INADDR_ANY" i odbierać zarówno pakiety emisji pojedynczej, jak i emisji w systemie HP-UX. – goose
Tak, wydaje się, że musisz wybrać. Wysłałem teraz kanoniczną odpowiedź na twoje pytanie. Jestem jednak nieco oszołomiony tym, dlaczego zachowanie różni się w Linuksie od HP-UX (choć istnieją argumenty przemawiające za tym, dlaczego lepsze byłoby rozdzielenie emisji i emisji pojedynczej). Dla mnie to sugeruje, że nie wiemy wszystkiego, i, cóż, to niedopuszczalne jak zwykle. Mam ochotę napisać kilka programów testowych w C, aby w pełni rozwinąć opcje emisji na Linuksie, chociaż nie mam HP-UX ... Do tego czasu mam nadzieję, że moja odpowiedź to obejmie. –