2009-08-25 12 views
8

यदि कोई टीसीपी सर्वर और क्लाइंट कनेक्ट है, तो मैं यह निर्धारित करना चाहता हूं कि क्लाइंट अब कनेक्ट नहीं होगा। मैंने सोचा कि मैं क्लाइंट को एक संदेश भेजने का प्रयास करके बस ऐसा कर सकता हूं और एक बार() को -1 के साथ रिटर्न भेजता हूं, फिर मैं सॉकेट को फाड़ सकता हूं। यह कार्यान्वयन विंडोज़ पर काम करता है लेकिन जिस समय मैं इसे बीएसडी सॉकेट के साथ लिनक्स पर करने का प्रयास करता हूं, सर्वर साइड ऐप पर भेजने के लिए कॉल() क्लाइंट अब कनेक्ट नहीं होने पर मेरे सर्वर ऐप को क्रैश कर देता है। यह एक -1 भी वापस नहीं करता है ... सिर्फ कार्यक्रम को समाप्त करता है।टीसीपी भेजें क्रैशिंग प्रक्रिया कारण नहीं लौटाता

कृपया बताएं कि यह क्यों हो रहा है। अग्रिम में धन्यवाद!

उत्तर

13

यह सिगिप सिग्नल के कारण होता है। send(2) देखें: अगर

भेजने() फ़ंक्शन असफल होंगे:
[EPIPE] सॉकेट नीचे लिखने के लिए बंद है, या सॉकेट कनेक्शन मोड है और अब जुड़ा हुआ है। बाद के मामले में, और यदि सॉकेट SOCK_STREAM या SOCK_SEQPACKET प्रकार है और MSG_NOSIGNAL ध्वज सेट नहीं है, तो सिगिपिप सिग्नल कॉलिंग थ्रेड पर जेनरेट किया गया है।

आप, या अपने कार्यक्रम की शुरुआत में signal(SIGPIPE, SIG_IGN) साथ SIGPIPE संकेत की अनदेखी करके send() फोन पर MSG_NOSIGNAL ध्वज का उपयोग करके इस से बच सकते हैं। फिर send() फ़ंक्शन -1 लौटाएगा और इस स्थिति में errnoEPIPE पर सेट करेगा।

2

आपको सिगिप सिग्नल को अनदेखा करने की आवश्यकता है। यदि किसी सॉकेट पर कोई त्रुटि त्रुटि होती है, तो आपकी प्रक्रिया SIGPIPE प्राप्त करने के साथ होती है, और उस सिग्नल का डिफ़ॉल्ट व्यवहार आपकी प्रक्रिया को मारना है। * निक्स पर नेटवर्किंग कोड लिखना आप आमतौर पर चाहते हैं:

signal(SIGPIPE,SIG_IGN);