2009-03-02 21 views

उत्तर

-1

मल्टीकास्ट यातायात आईपी पते को छोड़कर नियमित यूडीपी से अलग नहीं है। मानक socket library पर एक नज़र डालें। आप सॉकेट पर जो कुछ भी बनाते हैं उसे ढूंढने में सक्षम हो सकते हैं और उपयोग करना आसान है।

+0

दाएं। लेकिन एक समूह में शामिल होने के बारे में कैसे? यदि संभव हो तो मैं अपने समूह में प्रबंधन में शामिल नहीं होना चाहता हूं। –

+7

मल्टीकास्ट यातायात _quite_ नियमित (यूनिकास्ट) यूडीपी यातायात से अलग है: आपको मल्टीकास्ट समूह में शामिल होने की आवश्यकता है, सभी शामिल स्विच और राउटर को प्रभावों से निपटने की आवश्यकता है, टीटीएल मामलों, आमतौर पर डब्ल्यूएएन के माध्यम से नहीं जाते हैं। –

16

मल्टीकास्ट इस है कि एक बहुस्त्र्पीय समूह के लिए प्रसारण:

#!/usr/bin/env python 

import socket 
import struct 

def main(): 
    MCAST_GRP = '224.1.1.1' 
    MCAST_PORT = 5007 
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32) 
    sock.sendto('Hello World!', (MCAST_GRP, MCAST_PORT)) 

if __name__ == '__main__': 
    main() 

मल्टीकास्ट रिसीवर है कि एक बहुस्त्र्पीय समूह से कंसोल के लिए पढ़ता है और हेक्स डेटा प्रिंट:

#!/usr/bin/env python 

import socket 
import binascii 

def main(): 
    MCAST_GRP = '224.1.1.1' 
    MCAST_PORT = 5007 
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
    try: 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    except AttributeError: 
    pass 
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32) 
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) 

    sock.bind((MCAST_GRP, MCAST_PORT)) 
    host = socket.gethostbyname(socket.gethostname()) 
    sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(host)) 
    sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, 
        socket.inet_aton(MCAST_GRP) + socket.inet_aton(host)) 

    while 1: 
    try: 
     data, addr = sock.recvfrom(1024) 
    except socket.error, e: 
     print 'Expection' 
     hexdata = binascii.hexlify(data) 
     print 'Data = %s' % hexdata 

if __name__ == '__main__': 
    main() 
+0

मैंने कोशिश की, यह काम नहीं किया। वायर्सहार्क में मैं ट्रांसमिट देख सकता हूं, लेकिन मुझे कोई आईजीएमपी सामग्री शामिल नहीं है और मुझे कुछ भी नहीं मिला है। –

+1

आपको मल्टीकास्ट समूह/पोर्ट मल्टीकास्ट पते पर स्थानीय बंदरगाह से बंधने की आवश्यकता नहीं है, 'sock.bind ((MCAST_GRP, MCAST_PORT)) ' – stefanB

+0

यह उदाहरण मेरे लिए एक अस्पष्ट कारण के लिए काम नहीं करता है। इंटरफ़ेस का चयन करने के लिए socket.gethostbyname (socket.gethostname()) का उपयोग करना हमेशा बाहरी इंटरफ़ेस का चयन नहीं करता है - वास्तव में, डेबियन सिस्टम पर, यह लूपबैक पता का चयन करता है। मेजबाननाम के लिए मेजबान तालिका में डेबियन 127.0.1.1 की प्रविष्टि जोड़ता है। इसके बजाय, यह socket.INADDR_ANY का उपयोग करने के लिए अधिक प्रभावी है, जो उच्च रैंकिंग उत्तर 'पैक' कथन के माध्यम से उपयोग करता है (जो '+' से अधिक सही है)। साथ ही, IP_MULTICAST_IF का उपयोग आवश्यक नहीं है, क्योंकि उच्च रैंकिंग उत्तर सही ढंग से बताता है। –

78

यह मेरे लिए काम करता है:

import socket 
import struct 

MCAST_GRP = '224.1.1.1' 
MCAST_PORT = 5007 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
sock.bind(('', MCAST_PORT)) # use MCAST_GRP instead of '' to listen only 
          # to MCAST_GRP, not all groups on MCAST_PORT 
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 

while True: 
    print sock.recv(10240) 
प्राप्त करें

भेजें

import socket 

MCAST_GRP = '224.1.1.1' 
MCAST_PORT = 5007 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) 
sock.sendto("robot", (MCAST_GRP, MCAST_PORT)) 

यह http://wiki.python.org/moin/UdpCommunication से उदाहरण हैं जो काम नहीं किया पर आधारित है।

मेरे प्रणाली है ... लिनक्स 2.6.31-15-जेनेरिक # 50 उबंटू SMP मंगल नवम्बर 10 14:54:29 यूटीसी 2009 i686 जीएनयू/लिनक्स अजगर 2.6.4

+6

मैक ओएस एक्स के लिए आपको सॉकेट.SO_REUSEPORT विकल्प को सॉकेट .O_REUSEADDR के विकल्प के रूप में उपयोग करने की आवश्यकता है, उसी मल्टीकास्ट पोर्ट एड्रेस संयोजन पर एकाधिक श्रोताओं को अनुमति देने के लिए। – atikat

+0

भेजने के लिए, मुझे "sock.bind ((, 0)" की भी आवश्यकता है) "क्योंकि मेरा मल्टीकास्ट श्रोता एक विशिष्ट एडाप्टर से जुड़ा हुआ था। Udp मल्टीकास्ट के लिए –

+2

आपको मल्टीकास्ट समूह/बंदरगाह से स्थानीय समूह पोर्ट, 'sock.bind ((MCAST_GRP, MCAST_PORT)) से जुड़ने की आवश्यकता नहीं है,' आपका कोड हो सकता है और काम नहीं कर सकता है, यह तब काम नहीं कर सकता जब आपके पास एकाधिक nics – stefanB

2

एक नज़र py-multicast पर। नेटवर्क मॉड्यूल जांच सकता है कि कोई इंटरफ़ेस मल्टीकास्ट का समर्थन करता है (कम से कम लिनक्स पर)।

import multicast 
from multicast import network 

receiver = multicast.MulticastUDPReceiver ("eth0", "238.0.0.1", 1234) 
data = receiver.read() 
receiver.close() 

config = network.ifconfig() 
print config['eth0'].addresses 
# ['10.0.0.1'] 
print config['eth0'].multicast 
#True - eth0 supports multicast 
print config['eth0'].up 
#True - eth0 is up 

शायद आईजीएमपी नहीं देखे जाने में समस्याएं इंटरफेस के कारण मल्टीकास्ट का समर्थन नहीं कर रही थीं?

+0

http://coobs.eu.org/py-multicast/ लिंक टूटा हुआ है – balki

+2

तो यह है :(, अभी के लिए आप इसे आजमा सकते हैं: http://pypi.python.org/pypi/py-multicast – wroniasty

8

बेहतर इस्तेमाल:

sock.bind((MCAST_GRP, MCAST_PORT)) 

के बजाय:

sock.bind(('', MCAST_PORT)) 

... अगर आप एक ही बंदरगाह पर एक से अधिक mcast समूहों सुनना चाहते हैं, तो आप सभी पर सभी संदेशों को मिलेगा क्योंकि श्रोताओं

0

टोलोमा के जवाब ने मेरे लिए काम किया। मैं इसे socketserver.UDPServer में भी काट दिया:

class ThreadedMulticastServer(socketserver.ThreadingMixIn, socketserver.UDPServer): 
    def __init__(self, *args): 
     super().__init__(*args) 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.socket.bind((MCAST_GRP, MCAST_PORT)) 
     mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 
     self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 
0

(tolomea से) ग्राहक कोड बनाने के सोलारिस पर काम आप एक अहस्ताक्षरित चार के रूप में IP_MULTICAST_TTL सॉकेट विकल्प के लिए TTL मान उत्तीर्ण करने की आवश्यकता है। अन्यथा आपको एक त्रुटि मिलेगी। यह सोलारिस 10 और 11 पर मेरे लिए काम किया:

import socket 
import struct 

MCAST_GRP = '224.1.1.1' 
MCAST_PORT = 5007 
ttl = struct.pack('B', 2) 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) 
sock.sendto("robot", (MCAST_GRP, MCAST_PORT)) 
1

आदेश बहुस्त्र्पीय समूह अजगर देशी ओएस सॉकेट इंटरफ़ेस का उपयोग करता शामिल होने के लिए।पाइथन पर्यावरण की पोर्टेबिलिटी और स्थिरता के कारण सॉकेट विकल्पों में से कई सीधे मूल सॉकेट सेटॉकटॉप कॉल पर अग्रेषित किए जाते हैं। ऑपरेशन के मल्टीकास्ट मोड जैसे कि समूह सदस्यता में शामिल होना और छोड़ना केवल setsockopt द्वारा पूरा किया जा सकता है।

मल्टीकास्ट IP पैकेट प्राप्त करने के लिए मूल कार्यक्रम देख सकते हैं जैसे:

from socket import * 

multicast_port = 55555 
multicast_group = "224.1.1.1" 
interface_ip = "10.11.1.43" 

s = socket(AF_INET, SOCK_DGRAM) 
s.bind(("", multicast_port)) 
mreq = inet_aton(multicast_group) + inet_aton(interface_ip) 
s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, str(mreq)) 

while 1: 
    print s.recv(1500) 

सबसे पहले यह सॉकेट बनाता है, जिसे बांधता है और बहुस्त्र्पीय समूह setsockopt जारी करके शामिल होने से चलाता है चलाता है। बहुत अंत में यह हमेशा के लिए पैकेट प्राप्त करता है।

मल्टीकास्ट आईपी फ्रेम भेजना सीधे आगे है। यदि आपके पास ऐसे सिस्टम भेजने वाले आपके सिस्टम में एकल एनआईसी सामान्य यूडीपी फ्रेम भेजने से अलग नहीं है। आपको केवल sendto() विधि में सही गंतव्य आईपी पता सेट करने की आवश्यकता है।

मैंने देखा कि इंटरनेट के आसपास कई उदाहरण वास्तव में दुर्घटना से काम करते हैं। आधिकारिक पायथन दस्तावेज पर भी। उन सभी के लिए समस्या गलत तरीके से struct.pack का उपयोग कर रहे हैं। कृपया सलाह दीजिये कि सामान्य उदाहरण प्रारूप के रूप में 4sl का उपयोग करता है और यह वास्तविक ओएस सॉकेट इंटरफेस संरचना के साथ गठबंधन नहीं है।

मैं पाइथन सॉकेट ऑब्जेक्ट के लिए सेटॉकटॉप कॉल का उपयोग करते समय हुड के नीचे क्या होता है इसका वर्णन करने की कोशिश करूंगा।

पायथन आगे देशी सी सॉकेट इंटरफ़ेस को सेटॉकॉप विधि कॉल करें। लिनक्स सॉकेट दस्तावेज (man 7 ip देखें) IP_ADD_MEMBERSHIP विकल्प के लिए ip_mreqn संरचना के दो रूप प्रस्तुत करता है। सबसे छोटा रूप 8 बाइट लंबा है और लंबा 12 बाइट लंबा है। उपरोक्त उदाहरण 8 बाइट setsockopt कॉल उत्पन्न करता है जहां बाइट्स के लिए मुट्ठी multicast_group और दूसरा interface_ip परिभाषित करता है।

संबंधित मुद्दे