特定客户端/服务器多播配置

时间:2012-01-07 22:10:32

标签: python udp multicast

我正在尝试配置多播接口以执行以下操作:
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

编辑:
仅使用一台机器进行测试。

我的代码如下:

'''
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 个答案:

答案 0 :(得分:1)

服务器和客户端都需要打开一个端口,服务器是一个端口,它从客户端接收“88”消息,客户端接收组播端口。但是,在客户端中,您永远不会将套接字绑定到端口。

self.socket.bind(("", MULTICAST_PORT))

在该示例中,您也碰巧使用相同的端口与客户端/服务器作为多播端口进行通信,并且由于您在一台计算机上运行它会导致麻烦(据我所知,进程无法共享端口)。

将端口运行与另一个端口绑定后进行客户端/服务器通信。

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

这应该适合你(在我的机器上......以及在虚拟机设置中......)。如果您坚持只使用一个端口,那么您需要使用两台机器。

编辑错过了它在一台计算机上测试过。