2012-09-13 26 views
14

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

bool is_connected(int sock) 
{ 
    unsigned char buf; 
    int err = recv(sock,&buf,1,MSG_PEEK); 
    return err == -1 ? false : true; 
} 

बुरा बात यह है कि यह काम नहीं करता है। जब कोई डेटा प्राप्त नहीं होता है तो यह लटकता है। मैं क्या कर सकता हूँ? मैं जांच कैसे कर सकता हूं कि कनेक्शन अभी भी खुला है या नहीं?

+3

http://stackoverflow.com/questions/4142012/how-to-find-the-socket-connection-state-in-c – BoBTFish

उत्तर

17

पहले जांचें और फिर भेजें। यह बर्बाद प्रयास है और वैसे भी काम नहीं करेगा - जब आप चेक करते हैं और जब आप भेजते हैं तो स्थिति बदल सकती है। बस वही करें जो आप करना चाहते हैं और अगर यह विफल रहता है तो त्रुटि को संभालें।

स्थिति की जांच करने के लिए, का उपयोग करें:

int error_code; 
int error_code_size = sizeof(error_code); 
getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size); 
+1

सच है ... लेकिन कभी-कभी यह जांचना उपयोगी होता है कि सॉकेट अभी भी कनेक्ट है या नहीं। इसे गैर-ब्लॉक पर सेट करना, और उसके बाद peek_msg के साथ पढ़ना एक सॉकेट कोड प्राप्त करने का एक अच्छा तरीका है यह जांचने के लिए कि सॉकेट अभी भी जुड़ा हुआ है। –

+2

@RafaelBaptista क्यों? * का उपयोग * यह जांच करेगा। डेविड ऊपर दिए जाने के कारण, पहले परीक्षण करना भरोसेमंद काम नहीं कर सकता है। – EJP

+0

@EJP: मैं क्लाइंट कनेक्शन को जीवित रखना चाहता हूं इसलिए मैं संसाधनों को बर्बाद नहीं करता हूं। – che

12

का उपयोग करके O_NONBLOCK सेट करके आपको गैर-अवरुद्ध व्यवहार को सक्षम करने की आवश्यकता है। एक आसान लेकिन गैर मानक तरीका एक गैर अवरुद्ध पढ़ने करने के लिए उपयोग करने के लिए होगा:

recv(sock, &buf, 1, MSG_PEEK | MSG_DONTWAIT); 

बाद में, आप चाहिए जांच errno अगर यह विफल रहता है। यह EAGAIN साथ असफल हो सकता है या यह EBADF या ENOTCONN आदि


जाहिर है, इस से निपटने के लिए से बचने के लिए "भूल" यदि सॉकेट या जुड़ा हुआ नहीं है हो सकता है सबसे सरल और स्पष्ट तरीका के साथ विफल कर सकते हैं। recv रिटर्न 0 या send रिटर्न EPIPE पर एक बार सॉकेट डिस्कनेक्ट हो जाने पर आपको नोटिस हो जाएगा।

+2

यह नहीं होगा सभी कनेक्शन विफलताओं का पता लगाएं। केवल एक भेज() कर सकते हैं। – EJP

+0

@EJP वास्तव में यह सच है। मैं सिर्फ ओप के समाधान में सुधार कर रहा था। आप जो सुझाव दे रहे हैं वह एकमात्र बुलेट प्रूफ समाधान है, लेकिन इसमें भेजने की आवश्यकता है। – cnicutar

2

टीसीपी का डिफ़ॉल्ट उपयोग मृत सॉकेट (सामान्य बंद होने के बाहर) के समय पर पता लगाने की अनुमति नहीं देता है, इसलिए मैं सुझाव दूंगा कि इस तरह का "is_connected" फ़ंक्शन काफी व्यावहारिक उद्देश्यों के लिए बेकार है। समय-समय पर प्रतिक्रियाओं (या इसकी कमी) के आधार पर जीवित रहने पर एप्लिकेशन-लेयर को जीवित रखने और ट्रैक करने पर विचार करें।

संपादित करें: पोस्ट करने के बाद मुझे बीओबीटीफ़िश का लिंक दिखाई देता है, जो प्रभावी रूप से एक ही चीज़ है।

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