2012-07-30 275 views
2

我有一台计算机有5个接口:3与公共IP和2本地IP。我试图将“HELLO”发送到UDP服务器,但我想将接口更改为本地IP地址之一。我做了一些研究,这是我需要在Python添加一行:如何更改套接字的IP_MULTICAST_IF

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) 

,并使用双绞线:

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() 
+1

“它不起作用”不是一个非常有用的问题描述。 'setsockopt'成功或失败了吗? sendto'成功或失败了吗? – 2012-07-30 07:41:28

+1

@SquallLeohart:你想测试的服务器和本地地址(私有地址)在同一台机器上? – TOC 2012-07-30 08:38:33

+0

当我使用[RFC 1918](http://tools.ietf.org/html/rfc1918)地址时,我对这段代码没有任何问题; wireshark显示组播数据包无问题 – 2012-07-30 11:55:46

回答

1

答案:我的防火墙不接受来自该RFC1918 IP地址的udp数据包。

1

在情况下,服务器和客户端是在同一台机器上(因为我用两种方式收听测试),也许你需要设置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 

问候。

+0

它不起作用。 当我切换它们时,似乎具有类似IP地址的接口没有问题,例如64.195.10.110,64.195.10.11,64.195.10.12 但是例如192.168.1.75是我无法切换到的地址。 – 2012-07-30 17:09:15

+0

@SquallLeohart:你可以使用tcpdump并在这里转储一些数据包吗? – TOC 2012-07-30 18:20:15

+0

@SquallLeohart:你可以发布你的所有代码吗? – TOC 2012-07-30 18:34:52

相关问题