2012-01-07 7 views
0

私は、次のことを行うために、マルチキャストインターフェイスを設定しようとしている:
1)サーバ - 唯一の彼の特定のIP
2のために送られたデータをリッスン、マルチキャストグループにデータを送信)クライアント - サーバのみ特定のクライアント/サーバ・マルチキャストの設定

にデータを送信し、マルチキャストグループのデータを受け取るには、しかし、私が取得していますものです:
サーバ - マルチキャストグループにデータを送信し、それを受けて、彼の特定のIP
クライアントのためにデータを取得する - データを送信しますサーバーに接続し、マルチキャストグループのデータを取得しません。

私はセットアップ:

lo  Link encap:Local Loopback 
      inet addr:127.0.0.1 Mask:255.0.0.0 
      inet6 addr: ::1/128 Scope:Host 
      UP LOOPBACK RUNNING MTU:16436 Metric:1 


p1p1  Link encap:Ethernet HWaddr XXX 
      inet addr:192.168.1.91 Bcast:192.168.1.255 Mask:255.255.255.0 
      inet6 addr: XXX Scope:Link 
      UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 

使用法:

Server: $ python multicast.py -s --sp 10000 
Client: $ python multicast.py -c --sip localhost --sp 10000 

EDIT:のみ1機を使用してテスト

私のコードは以下の通りです:

''' 
Created on Dec 16, 2011 

@author: wysek 
''' 

import sys 
import socket 
import struct 
import threading 
import pickle 

from itertools import product 
from optparse import OptionParser 
from random import randint as rand 
from time import sleep 

############################################################################################################ 

MULTICAST_GROUP = "226.1.1.1" 
MULTICAST_PORT = 10000 

class Server(object): 
    def __init__(self, serv_port): 
     self.myport = serv_port 
     try: 
      print "DEBUG: CREATING SOCKET" 
      self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
      self.socket.bind(("", self.myport)) 
      self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1) 
      self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
      self.socket.settimeout(0.2) 
     except socket.error, err: 
      print "ERROR: EXCEPTION DURING INITIALIZING SERVER'S SOCKET - %s" % err 
      sys.exit(1) 
     else: 
      print "DEBUG: SOCKET CREATED" 
      self.receiver() 

    def receiver(self): 
     print "DEBUG: WAITING FOR DATA" 
     while True: 
      try: 
       msg, who = self.socket.recvfrom(1024) 
      except socket.timeout: 
       continue 
      except socket.error, err: 
       print "ERROR: EXCEPTION DURING RECEIVEING AND READING DATAGRAM - %s" % err 
      except KeyboardInterrupt: 
       print "DEBUG: KEYBOARD INTERRUPT (CTRL+C)" 
       self.__del__() 
       return 
      else: 
       print "MSG: %s \nFROM: %s" % (msg, who) 
       self.msg_handle(msg) 

    def msg_handle(self, msg): 
     msg = int(msg) 
     if msg == 88: 
      print "DEBUG: RECEIVED CONNECTION REQUEST" 
      self.msg_sending("1") 
     else: 
      print "ERROR: Unknown nr (%s) received" % msg 

    def msg_sending(self, msg): 
     try: 
      print "DEBUG: SENDING - %s" % msg 
      self.socket.sendto(msg, (MULTICAST_GROUP, MULTICAST_PORT)) 
     except socket.error, err: 
      print "ERROR: MESSAGE \"%s\" COULDN'T BEEN SENT DUE TO THE: %s." % (msg, err) 

    def __del__(self): 
     print "DEBUG: CLOSING SOCKET" 
     self.socket.close() 
     print "DEBUG: SOCKET CLOSED" 

############################################################################################################ 

class Client(object): 

############################################################################################################ 

    class NetworkThread(threading.Thread): 

     def __init__(self, parent, serv): 
      threading.Thread.__init__(self) 
      self.serv = serv 
      self.status = 1 
      self.parent = parent 

      try: 
       print "DEBUG: CREATING SOCKET" 
       self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
#    self.ttl = struct.pack('b', 1) 
       self.group = socket.inet_aton(MULTICAST_GROUP) 
       self.mreq = struct.pack('=4sl', self.group, socket.INADDR_ANY) 
       self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, self.mreq) 
       self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
       print "DEBUG: TRYING TO CONNECT" 
       self.msg_sending(str(88)) 
       data, serv = self.socket.recvfrom(1024) 
       print str(data) + " from " + str(serv) 

      except socket.error, err: 
        print "ERROR: EXCEPTION DURING INITIALIZING SERVER'S SOCKET DUE TO THE: %s" % err 
        sys.exit(1) 

     def msg_sending(self, msg): 
      try: 
       self.socket.sendto(msg, self.serv) 
      except socket.error, err: 
       print "ERROR: Message \"%s\" COULDN'T BEEN SENT DUE TO THE: %s." % (msg, err) 

     def __del__(self): 
      print "DEBUG: CLOSING SOCKET" 
      self.socket.close() 
      print "DEBUG: SOCKET CLOSED" 

############################################################################################################ 

    def __init__(self, serv): 
     self.networking = self.NetworkThread(self, serv) 
     self.networking.run() 

    def __del__(self): 
     print "DEBUG: JOINED - EXITING. HAVE A NICE DAY." 

############################################################################################################ 

if __name__ == "__main__": 
    parser = OptionParser() 
    parser.add_option("", "--sp", action="store", type="int", dest="serv_port") 
    parser.add_option("", "--sip", action="store", type="string", dest="serv_ip") 
    parser.add_option("-c", "", action="store_true", dest="client") 
    parser.add_option("-s", "", action="store_true", dest="server") 
    options, args = parser.parse_args() 
    if not (options.server or options.client): 
     print "ERROR: Client/Server not specified. Could not continue..." 
     sys.exit(1) 
    elif options.server and not options.serv_port: 
     print "ERROR: Server's ports not specified. Could not continue..." 
     sys.exit(1) 
    elif options.client and not (options.serv_port and options.serv_ip): 
     print "ERROR: Ports not specified. Could not continue..." 
     sys.exit(1) 
    else: 
     if options.server: 
      serv = Server(options.serv_port) 
     else: 
      client = Client((options.serv_ip, options.serv_port)) 

答えて

1

サーバーとクライアントの両方が開いているポートを持っている必要があり、サーバーがクライアントとクライアントマルチキャストポートから「88」のメッセージを受信するポート。しかし、クライアントではソケットをポートにバインドすることはありません。

(プロセスは限りポートを共有することはできませんあなたはまた、マルチキャストポートなどのクライアント/サーバーと通信するために同じポートを使用するように起こると、1台のマシン上でこれを実行するため、それがトラブルの原因となります例で
self.socket.bind(("", MULTICAST_PORT)) 

知っている)。

ポート実行をクライアント/サーバー通信用の別のポートでバインドした後。

$ python multicast.py -s --sp 20000 
$ python multicast.py -c --sip localhost --sp 20000 

これは私のマシンでもうまくいきます(仮想マシンのセットアップでも同様です)。 1つのポートしか使用しないと主張する場合は、2台のマシンを使用する必要があります。

EDIT 1台のマシンでテストされていませんでした。

+0

この例では:http://www.doughellmann.com/PyMOTW/socket/multicast.html Dougは送信者を拘​​束していませんが、まだ彼は聞くことができます。なぜ私のサーバーは登録されたメンバーではないのにマルチキャストグループからデータを取得するのですか? – Michal

+1

彼は送信者を聞くのではなく、受信者を聞いています。あなたのコードがメンバではなくマルチキャストメッセージを受信する理由は、2つのマシンを使用しているときや別のポートを使用しているときには起こらないので、同じポート番号の過度使用によるバグだと考えてください。 –

+0

うん、あなたは正しい。私は聞いていませんでした。ご回答有難うございます。同じ問題を抱えている人にとって、私の解決策は、クライアントとサーバーに2つの別個のソケットを作成することでした。 1つはマルチキャスト(クライアントはこのサーバでのみ受信し、サーバは送信のみ)用で、もう1つはP2P通信用(サーバはリッスン、クライアントからの送信)です。 – Michal

関連する問題