2011-06-16 11 views
9

मैं पाइथन के लिए नया हूं और वर्तमान में एक स्क्रिप्ट के रूप में चलाने के लिए एक पाइथन सॉकेट लिखना है जो टीसीपी/आईपी (एक मौसम स्टेशन) पर किसी डिवाइस के साथ संचार करता है।
डिवाइस सर्वर साइड के रूप में कार्य करता है (आईपी पर सुनना: पोर्ट, कनेक्शन स्वीकार करना, अनुरोध प्राप्त करना, डेटा स्थानांतरित करना)।
मुझे केवल एक संदेश भेजने की आवश्यकता है, जवाब प्राप्त करें और फिर शांतिपूर्वक और अच्छी तरह से बंद करें और सॉकेट बंद करें। पायथन: गैर-अवरुद्ध सॉकेट या असिंक्रोनोस I/O

try: 
    comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except socket.error, msg: 
    sys.stderr.write("[ERROR] %s\n" % msg[1]) 
    sys.exit(1) 

try: 
    comSocket.connect(('')) 
except socket.error, msg: 
    sys.stderr.write("[ERROR] %s\n" % msg[1]) 
    sys.exit(2) 

comSocket.send('\r') 
comSocket.recv(128) 
comSocket.send('\r') 
comSocket.recv(128) 
comSocket.send('\r\r') 
comSocket.recv(128) 

comSocket.send('1I\r\r3I\r\r4I\r\r13I\r\r5I\r\r8I\r\r7I\r\r9I\r\r') 

rawData = comSocket.recv(512) 

comSocket.shutdown(1) 
comSocket.close() 

समस्या मैं आ रही है:
संचार चैनल अविश्वसनीय है, डिवाइस धीमी है। इसलिए, कभी-कभी लंबाई 0 (केवल एक एसीके) के संदेश के साथ डिवाइस प्रतिक्रिया, मेरा कोड स्थिर हो जाएगा और हमेशा के लिए प्रतिक्रिया की प्रतीक्षा करेगा।
कोड का यह टुकड़ा उस हिस्से में होता है जिसमें सॉकेट शामिल होता है, पूरा कोड सीआरओएन के तहत चलाया जाएगा, इसलिए ठंड एक वांछनीय व्यवहार नहीं है।

मेरा प्रश्न है:
, उस व्यवहार को संभालने के लिए इतना है कि कोड जमता नहीं और हमेशा के लिए इंतजार अजगर में सबसे अच्छा तरीका होगा, लेकिन (या ऐसे) अगले भेजने पर जाने के लिए प्रयास करेंगे क्या ।

+5

आपको पायथन के लिए [ट्विस्टेड] (http://twistedmatrix.com/) लाइब्रेरी पर एक नज़र रखना चाहिए। यह एसिंक्रोनस नेटवर्किंग के लिए एक ढांचा है जो इसे अधिक आसान बना देगा। – Andrea

+0

ट्विस्ट लाइब्रेरी का उपयोग करते समय काम कर सकता है, एक संदेश के लिए एक संपूर्ण लाइब्रेरी थोड़ा अधिक लगता है। शायद आपको सीआरओएन को एक अलग थ्रेड में चलने वाले सॉकेट संचार के साथ एक उपप्रोसेसर खोलने की आवश्यकता है। इस तरह आप अवरुद्ध मुद्दे से बचेंगे। – chisaipete

+0

@Andrea क्योंकि मेरे पास पोस्ट किए गए एक से समान प्रश्न हैं। क्या सर्वर साइड के लिए ट्विस्ट नहीं बनाया गया है? क्लाइंट साइड पर उपयोग करने के लिए इसे कैसे संशोधित करें? – Hangon

उत्तर

0

प्रयास करें, प्राप्त करना, सॉकेट पर एक टाइमआउट डालने से पहले:

comSocket.settimeout(5.0) 
try: 
    rawData = comSocket.recv(512) 
except socket.timeout: 
    print "No response from server" 
3

मैं eventlet और हरे रंग के धागे इस के लिए सलाह देते हैं।

ट्विस्ट एक अच्छी लाइब्रेरी है लेकिन इस तरह के एक साधारण उपयोग मामले के लिए थोड़ा सीधी सीखने की वक्र है।

कुछ उदाहरण देखें here

11

आप रसेल कोड की तरह टाइमआउट दृष्टिकोण का प्रयास कर सकते हैं या आप नीचे दिए गए कोड में दिखाए गए अनुसार एक गैर-अवरुद्ध सॉकेट का उपयोग कर सकते हैं। यह socket.recv पर कभी भी अवरुद्ध नहीं होगा और आप जितनी बार चाहें पुनः प्रयास करने के लिए इसे लूप के अंदर उपयोग कर सकते हैं। इस तरह आपका प्रोग्राम टाइमआउट पर नहीं लटका होगा। इस तरह, आप परीक्षण कर सकते हैं कि डेटा उपलब्ध है और यदि नहीं, तो आप अन्य चीजें कर सकते हैं और बाद में पुनः प्रयास कर सकते हैं।

socket.setblocking(0) 
while (retry_condition): 
    try: 
     data = socket.recv(512) 
    except socket.error: 
     '''no data yet..''' 
संबंधित मुद्दे