3

私は5つのインターフェースを備えたコンピューターを持っています:3つはパブリックIP、2つはローカルIPです。「HELLO」をUDPサーバーに送信しようとしていますが、インターフェイスをローカルIPアドレスの1つに変更したいと思います。私はいくつかの調査を行いました、そしてこれは私が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

編集:私は2つの方法を使用して聞いています:

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()
4

2 に答える 2

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

よろしく。

于 2012-07-30T14:25:03.373 に答える
1

答え:私のファイアウォールは、そのRFC1918IPアドレスからのudpパケットを受け入れませんでした。

于 2012-07-30T19:46:12.237 に答える