2012-06-04 12 views
7

सुन मैं एक ऐप्स, सॉफ्टवेयर परिभाषित रेडियो, कि एक बंदरगाह है कि श्रोताओं क्या आवृत्ति और demodulation मोड सेट कर दिया है बता पर यूडीपी पैकेट का प्रसारण करता है (अन्य बातों के अलावा।)अजगर और यूडीपी

मैं एक डेमो लिखा है है पाइथन क्लाइंट (नीचे कोड) जो बंदरगाह को सुनता है, और कंसोल पर उपयुक्त पैकेट में जानकारी को डंप करता है।

ये दोनों ओएसएक्स 10.6, हिम तेंदुए के तहत चल रहे हैं। वे वहां काम करते हैं।

मेरे पास प्रश्न/मुद्दा है: पाइथन ऐप को रेडियो ऐप से पहले शुरू करना है या यह दावा करता है कि बंदरगाह के दौरान बंदरगाह पहले से ही उपयोग में है (ERRNO 47), और मुझे समझ में नहीं आता क्यों। रेडियो ऐप यूडीपी प्रसारित कर रहा है; निश्चित रूप से मैं कई श्रोताओं को समायोजित करना चाहता हूं - यह प्रसारण का विचार है, या कम से कम, इसलिए मैंने सोचा।

तो यहाँ अजगर कोड (मांगपत्र एक छोटे में गड़बड़ अतिप्रवाह ढेर की वजह से है वास्तव में गूंगा है "कर यह कोड" मांगपत्र, लेकिन मैं विश्वास दिलाता हूं कि आप यह ठीक है) है:

#!/usr/bin/python 
import select, socket 

# AA7AS - for SdrDx UDP broadcast 

# this is a sample python script that captures the UDP messages 
# that are coming from SdrDx. SdrDx tells you what frequency and 
# mode it has been set to. This, in turn, would be used to tell 
# another radio to tune to that frequency and mode. 

# UDP packet from SdrDx is zero terminated, but receiving the 
# packet makes it seem like the string contains zeros all the 
# way out to the 1024th character. This function extracts a 
# python string up to the point where it hits the first zero, 
# then returns that string. 
# ----------------------------------------------------------- 
def zeroterm(msg): 
    counter = 0; 
    for c in msg: 
     if ord(c) != 0: 
      counter += 1 
    strn = msg[:counter] 
    return strn 

port = 58083  # port where we expect to get a msg 
bufferSize = 1024 # room for message 

# Create port to listen upon 
# -------------------------- 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
try: 
    s.bind(('', port)) 
except: 
    print 'failure to bind' 
    s.close() 
    raise 
    s.setblocking(0) 

# Listen for messages 
# ------------------- 
looping = True 

while looping: 
try: 
    result = select.select([s],[],[]) 
except: # you can kill the client here with control-c in its shell 
    s.close() # must close socket 
    print 'Closing, exception encountered during select' # warn 
    raise SystemExit # and quit 
msg = result[0][0].recv(bufferSize) # actually fetch the UDP data 
msg = zeroterm(msg) # convert content into python string 

# in next line, [] contain optional repeats 
# message format is keyword:data[|keyword:data] 
# where from 1...n keyword:data pairs may appear, up to 1024 bytes 
# ---------------------------------------------------------------- 

try: 
    msgs = msg.split('|')  # can be more than one message in packet 
except: # failed to split 
    msgs = []     # on the other hand, can just be one. :) 
    msgs.append(msg)   # so build array with that one. 
for m in msgs:     # now, for every message we have 
    keyw,data = m.split(':') # break into keyword and data 
    print keyw + "-->" + data # you'd do something with this 
    if keyw == "closing":  # Our client terminates when SdrDx does 
     looping = False   # loop stops 

s.close()       # must close socket 
print 'Normal termination' 

संदर्भ के लिए,

सेटअप::

bcast = new QHostAddress("192.168.1.255"); 
if (bcast) 
{ 
    udpSocketSend = new QUdpSocket(0); 
    if (udpSocketSend) 
    { 
     udpSocketSend->bind(*bcast, txudp); 
    } 
} 

प्रसारण:

यहाँ क्यूटी कोड कि यूडीपी संदेश भेज रहा है
if (udpSocketSend) 
{ 
    QByteArray *datagram = new QByteArray(1024,0); // datagram is full of zeroes 
    strcpy(datagram->data(),msg);     // except where text message is in it at beginning 
    udpSocketSend->writeDatagram(*datagram, QHostAddress::Broadcast,txudp); // send 
} 
+0

ये दो ऐप्स एक ही मशीन पर चल रहे हैं, हाँ? – jedwards

+0

आपको इंडेंटेशन को ठीक करने की आवश्यकता है। कोशिश करने के बाद: 'ऐसी कोई पंक्ति नहीं हो सकती है जिसमें' इंडेंट 'स्तर के समान इंडेंटेशन स्तर हो। – ThiefMaster

+0

@jedwards, हां। चोरमास्टर: जैसा कि मैंने स्पष्ट रूप से पायथन कोड के ठीक ऊपर कहा था, स्टैक ओवरफ्लो के स्वरूपण ने इंडेंट को गड़बड़ कर दिया था। कोड सही ढंग से इंडेंट किया गया है। वहां कोई चिंता नहीं है। – fyngyrz

उत्तर

6

आप एक ही बंदरगाह को दो बार बांधने की कोशिश कर रहे हैं।

आप इस में एक बार यह बाँध: रिसीवर

s.bind(('', port)) 

और इन के बाद से एक ही मशीन पर चल रहे हैं पर

if (udpSocketSend) 
{ 
    udpSocketSend->bind(*bcast, txudp); 
} 

और फिर, आप एक त्रुटि हो रही है।

जब तक आप स्रोत पोर्ट की परवाह नहीं करते हैं, तो आपको प्रेषक पर bind() की आवश्यकता नहीं है, बस इसे भेजें और स्टैक उचित आउटगोइंग स्रोत पोर्ट नंबर चुनेंगे। प्रेषक के मामले में, जब आप एक यूडीपी डेटाग्राम प्रेषित करते हैं तो आप गंतव्य (udpSocketSend->writeDatagram(...)) निर्दिष्ट करते हैं, और bind वास्तव में आउटगोइंग डेटाग्राम के स्रोत को निर्धारित करता है। यदि आप bind नहीं हैं, तो ठीक है, स्टैक आपको एक पोर्ट असाइन करेगा।

यदि आप पर ध्यान दें कि स्रोत पोर्ट क्या है, तो मेरा सुझाव है कि आप आउटगोइंग स्रोत पोर्ट और आने वाले गंतव्य पोर्ट के लिए एक अलग पोर्ट नंबर का उपयोग करें। फिर आप बिना किसी मुद्दे के प्रेषक और रिसीवर दोनों को बांधने में सक्षम होंगे।

आखिरकार, SO_REUSEADDR सॉकेट विकल्प (जो भी भाषा आप उपयोग कर रहे हैं) को सेट करने का विकल्प है। यह आवश्यक होगा यदि आप उसी मशीन पर एकाधिक क्लाइंट चलाएं, क्योंकि सभी क्लाइंटों को एक ही पते से जुड़ना होगा। लेकिन, मुझे यकीन नहीं है कि यह सॉकेट विकल्प क्रॉस प्लेटफार्म है (* निक्स ठीक काम करता है) और मुझे लगता है कि उपर्युक्त सुझाव बेहतर हैं।

+1

+1, लेकिन इसे पूरी तरह स्पष्ट करने के लिए, टीसीपी/आईपी संचार में, आप लगभग कभी भी ध्यान नहीं देते कि स्रोत पोर्ट क्या है। यदि आप फ़ायरवॉल नियमों के किसी विशेष सेट पर बातचीत करने की कोशिश कर रहे थे तो बहुत अधिक समय आप परवाह करेंगे। –

+0

रसेल: यह यूडीपी है। टीसीपी नहीं @jedwards: मुझे एक चैनल भेजने के लिए (सिंगल) एप्लिकेशन की आवश्यकता है जिसे कई क्लाइंट्स द्वारा प्राप्त किया जा सकता है। मुझे ग्राहकों की आवश्यकता है - संभवतः उनमें से कई - एप्लिकेशन को संदेश भेजने में सक्षम होने के लिए। किसी भी मामले में मैं चाहता हूं कि उपयोगकर्ता को वास्तव में कुछ भी सेट अप करना पड़े। ऐसा लगता है कि प्रसारण के विचार दोनों सिरों फिट (और कुछ भी वास्तव में लग रहा था।) क्या मैं गलत हूँ? – fyngyrz

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