2013-12-09 8 views
5

यह प्रश्न पायथन तक सीमित नहीं है। यह एक सामान्य सॉकेट सवाल है। मेरे पास एक गैर-अवरुद्ध सॉकेट है और एक मशीन से कनेक्ट करना चाहता है जो पहुंच योग्य है - दूसरी ओर बंदरगाह मौजूद नहीं है। क्यों चुनें (...) वैसे भी सफल? मुझे एक टाइमआउट की उम्मीद थी। sock.send (...) एक टूटी पाइप के साथ विफल रहता है। मैं कैसे निर्धारित कर सकता हूं कि चयन (...) के बाद सॉकेट वास्तव में कनेक्ट है या नहीं? अग्रिम धन्यवाद।गैर-अवरुद्ध कनेक्ट

import socket, errno, os, time, select 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.setblocking(0) 
err = sock.connect_ex(('192.168.178.21', 12345)) 
ready_to_read, ready_to_write, in_error = select.select([], [sock], [], timeout=5) 
#ready_to_write is set even 192.168.178.21:12345 does not exist. 

sock.setblocking(1) 
sock.send('foo') #this fails 
sock.close() 

उत्तर

4

वापसी मूल्यों की जांच करने का प्रयास करें। यहां बताया गया है कि मैं एक ऐसी ही स्थिति में प्राप्त होते हैं:

>>> import socket, errno, os, time, select 
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
>>> sock.setblocking(0) 
>>> err = sock.connect_ex(('10.0.0.1', 12345)) 
>>> import errno 
>>> print errno.errorcode[err] 
EINPROGRESS 
>>> print sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) 
61 
>>> print errno.errorcode[61] 
ECONNREFUSED 

select() कॉल शायद लौटा रहा है क्योंकि वहाँ सॉकेट पर एक असाधारण हालत था - जो है, इसके संबंध से इनकार कर दिया गया था।

मैं ऐसा करते हैं तो select() रिटर्न तुरंत:

>>> ready_to_read, ready_to_write, in_error = select.select([], [sock], []) 

और काफी दिलचस्प है, वापसी मान बिल्कुल मेल खा में पारित (यदि आप एक से अधिक सॉकेट था, संभावना है कि अलग होगा):

>>> print in_error 
[] 
>>> print ready_to_read 
[] 
>>> print ready_to_write 
[<socket._socketobject object at 0x10ccd0980>] 

select() के डिजाइनरों आप एक पाश में select() चलाने के लिए उम्मीद कर रहे हैं, और एक सॉकेट एक त्रुटि देता है, तो जब आप लिखने का प्रयास, सूची से निकालने के लिए जब लिखने में विफल रहता है।

  • होने तक प्रतीक्षा सॉकेट पढ़ सकते हैं और असफल है, तो उचित कार्रवाई करने का प्रयास करें:

    तो तुम पास कुछ विकल्प होते, मेरे सिर के ऊपर से की है।

  • getsockopt() का उपयोग करें जैसा कि मैंने ऊपर किया है यह जांचने के लिए कि क्या सॉकेट ठीक है या किसी त्रुटि स्थिति में है, इसके साथ कुछ भी करने का प्रयास करने से पहले।
+0

sock.getsockopt (सॉकेट.SOL_SOCKET, सॉकेट.SO_ERROR) ने मेरे लिए चाल बनाई। – HelloWorld

+1

ठीक है। ध्यान रखें कि 'getockopt() 'वापसी और सॉकेट को पढ़ने या लिखने के आपके प्रयास के बीच सॉकेट बंद हो सकता है। इसलिए आपको अभी भी भेजने/recv पर त्रुटियों को संभालने का प्रयास करना चाहिए। – mpontillo

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