我有一台带有5个接口的计算机:3个带有公共IP和2个本地IP。我试图将“HELLO”发送到UDP服务器,但我想将接口更改为其中一个本地IP地址。我做了一些研究,这是我需要在python中添加的行:
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton("64.195.10.11"))
64.195.10.11是我想要更改为
的IP所以我的python代码如下所示:
import socket
MCAST_GRP = '224.0.0.1'
MCAST_PORT = 10222
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton("64.195.10.10"))
sock.sendto("HELLO", (MCAST_GRP, MCAST_PORT))
当我在3个公共IP地址之间切换时,它可以正常工作。但是,如果我在参数中放置了本地IP,则它不起作用(数据包未传递)。我不确定脚本是否未发送,或者服务器是否未收到。发生了什么事?
SL
编辑:我正在用两种方式听:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 10222))
sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton("224.0.0.1") +
socket.inet_aton("64.195.10.11"))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
while True:
print >>sys.stderr, '\nwaiting to receive message'
data, address = sock.recvfrom(1024)
print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
print >>sys.stderr, data
print >>sys.stderr, 'sending acknowledgement to', address
sock.sendto('ack', address)
并使用twisted:
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from twisted.application.internet import MulticastServer
class MulticastServerUDP(DatagramProtocol):
def __init__ (self, group, name):
self.group = group
self.name = name
def startProtocol(self):
print '%s Started Listening' % self.group
self.transport.joinGroup(self.group)
def datagramReceived(self, datagram, address):
print "%s Received:"%self.name + repr(datagram) + repr(address)
reactor.listenMulticast(10222, MulticastServerUDP('224.0.0.1', 'SERVER1'), listenMultiple = True)
reactor.run()
答案 0 :(得分:2)
如果服务器和客户端在同一台机器上(用于测试),可能需要像这样设置IP_MULTICAST_LOOP
选项(c代码):
int loop_on = 1;
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop_on, sizeof(loop_on));
在python中你可以试试这样的东西:
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
希望得到这个帮助。
编辑:添加一些跟踪(来自我的Linux框)
我使用的代码与SquallLeohart发布的代码相同:
#! /usr/bin/python
import socket
MCAST_GRP = '224.0.0.1'
MCAST_PORT = 10222
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton("192.168.1.7"))
sock.sendto("HELLO", (MCAST_GRP, MCAST_PORT))
和
#! /usr/bin/python
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 10222))
sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton("224.0.0.1") +
socket.inet_aton("192.168.1.7"))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
while True:
print >>sys.stderr, '\nwaiting to receive message'
data, address = sock.recvfrom(1024)
print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
print >>sys.stderr, data
print >>sys.stderr, 'sending acknowledgement to', address
sock.sendto('ack', address)
我得到了这个输出:
waiting to receive message
received 5 bytes from ('192.168.1.7', 43761)
HELLO
sending acknowledgement to ('192.168.1.7', 43761)
waiting to receive message
received 5 bytes from ('192.168.1.7', 52326)
HELLO
sending acknowledgement to ('192.168.1.7', 52326)
waiting to receive message
使用tcpdump:
21:01:33.814728 IP localhost.localdomain.34956 > all-systems.mcast.net.10222: UDP, length 5
21:01:35.364605 IP localhost.localdomain.39078 > all-systems.mcast.net.10222: UDP, length 5
21:01:36.228477 IP localhost.localdomain.49926 > all-systems.mcast.net.10222: UDP, length 5
问候。
答案 1 :(得分:1)
答案是:我的防火墙不接受来自该RFC1918 IP地址的udp数据包。