UDP сокет многоадресная
Начну с того, что я не совсем сетевой эксперт. Я пытаюсь создать систему сокетов многоадресной рассылки UDP с четырьмя моделями B. RaspBerry Pi. В каждом Rpi работает скрипт-клиент для прослушивания (я буду называть его " listen.py ").
Случай 1 - я вполне могу отправить дейтаграмму, если я запускаю сервер сокетов (я назову его " server.py ") прямо внутри Rpi (по SSH, также с моим ноутбуком).
У меня есть: -listen.py при загрузке Rpi (здесь я создаю сокет-клиент); -Я запускаю server.py (server.py явно входит в Rpi). В этом случае я получаю ответ от всех 4 Rpi, которые присоединились к многоадресной группе (224.1.1.1).
Случай 2 - Я создал сокет-сервер Java и сокет-клиент Python на своем ноутбуке, и все работает отлично (тот же код, та же группа многоадресной рассылки, тот же порт многоадресной рассылки). Я пробовал также без многоадресной рассылки, используя только 'localhost', и все работает также. С помощью netstat я вижу многоадресную группу и порт.
netstat -lu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 224.1.1.1:21581 *:* //MulticastGroupIp:Port
udp 0 0 192.168.1.103:ntp *:* //Static ip of one Rpi
udp 0 0 *:ntp *:*
Моя проблема в том, что если я запускаю server.py с моего ноутбука (без SSH), у меня не будет ответа от listen.py, клиента сокета, который работает в Rpi. Мне абсолютно необходимо отправить датаграмму с моего ноутбука (я хочу класс Java) на 4 Rpi.
Я исключил возможности плохого кода, неправильной многоадресной IP-группы, неправильной многоадресной группы портов. Брандмауэр отключен на моем ноутбуке и маршрутизаторе. Параметр net.ipv4.ip_forward в Rpi равен 1. Я знаю, что UDP ненадежен, но здесь я говорю о 100% потерянной дейтаграммы. IGMP включен на моем маршрутизаторе D-Link. У меня такая же проблема с конфигурацией Ethernet и WiFi.
Мне действительно нужны другие идеи..... Поэтому я попытался написать здесь. Извините, это мой первый пост, и я новичок всего понемногу. Я буду признателен за любое предложение. Возможно, это что-то глупое, что я не могу понять.
Может быть, некоторые проблемы с таблицей маршрутизации???? Это мое:
route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default D-Link.Home 0.0.0.0 UG 0 0 0 wlan0
192.168.1.0 * 255.255.255.0 U 0 0 0 wlan0
заранее спасибо
Для меня код работает хорошо, и проблема не в этом, но если это может быть полезно, чтобы лучше понять ситуацию.....
Код server.py (бесполезно говорить, что на моем компьютере с Windows 7 установлен python):
import socket
import sys
# import time
print 'message:'
n = sys.stdin.readline()
n = n.strip('\n')
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 21581
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.sendto(n, (MCAST_GRP, MCAST_PORT))
или с Java (это именно то, что я хочу... серверный сокет Java, но на данный момент это не приоритет):
public class PythonScriptScan {
private static int portMulticasting = 21581;
// private boolean broadcast = true;
private DatagramSocket socket;
private String groupMulticast = "224.1.1.1"; // group address
private int delay = 3000;
public PythonScriptScan() {
try {
socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
System.exit(1);
}
}
public void start(String agentName) {
try {
InetAddress group = InetAddress.getByName(groupMulticast);
@SuppressWarnings("resource")
MulticastSocket s = new MulticastSocket(portMulticasting);
s.joinGroup(group);
// while (broadcast) {
byte[] buf = new byte[10240];
buf = agentName.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, portMulticasting);
System.out.println(packet);
socket.send(packet);
// OK, I'm done talking - leave the group...
s.leaveGroup(group);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
System.exit(0);
}
// }
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
System.out.println("Insert Message");
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
String agentName = sc.nextLine();
PythonScriptScan agent = new PythonScriptScan();
agent.start(agentName);
}
и listen.py (он запускается при загрузке в каждом Rpis, необходимая мне конфигурация с Ethernet, у каждого Rpis есть статический ip, и они правильно подключены к моему маршрутизатору D-link):
#!/usr/bin/python
import socket
import struct
import fcntl
import subprocess
import sys
import errno
import time
import os
# Create the socket
MCAST_GRP = "224.1.1.1"
MCAST_PORT = 21581
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
except socket.error, msg:
print 'Could not create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind to the server address
# sock.bind(('', MCAST_PORT))
sock.bind((MCAST_GRP, MCAST_PORT))
# Tell the operating system to add the socket to the multicast group on all interfaces
mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# Receive loop
try:
while True:
print >>sys.stderr, '\nWAITING TO RECEIVE MESSAGE'
d = sock.recvfrom(10240)
data = d[0]
addr = d[1]
print data.strip(), addr
finally:
print >>sys.stderr, 'closing socket'
sock.close()