मैं एसिंक्रोनस I/O का शोषण करने के लिए पूर्णता बंदरगाहों का उपयोग कर विंडोज एनटी में एक टीसीपी सर्वर लिख रहा हूं। मेरे पास एक टीसीपी सॉकेट क्लास है, एक टीसीपी सर्वर क्लास और कुछ (आभासी फ़ंक्शंस) कॉलबैक कॉल करने के लिए कॉल करते हैं जब I/O ऑपरेशन पूरा हो जाता है, उदा। ऑन रीड() जब एक पठन पूरा हो जाता है। जब कनेक्शन बंद हो जाता है, और इसी तरह कनेक्शन के लिए कनेक्शन चालू होता है और() पर भी ओपन() चालू होता है। मेरे पास सॉकेट के लिए हमेशा लंबित पढ़ा जाता है, इसलिए यदि सॉकेट प्रभावी रूप से डेटा प्राप्त करता है (पढ़ना आकार> 0 के साथ पूरा हो जाएगा) तो यह रेड() पर कॉल करता है, इसके बजाय यदि ग्राहक क्लाइंट साइड से सॉकेट बंद करता है (पढ़ना आकार == 0 के साथ पूरा हो जाएगा) यह Eof() पर कॉल करता है, और सर्वर को पता है कि जब ग्राहक सॉकेट को closesocket (server_socket) से बंद करता है; इसके पक्ष से।कुख्यात `ERROR_NETNAME_DELETED 'त्रुटि को एक त्रुटि माना जा सकता है?
सभी शान से काम करता है, लेकिन मैं एक बात पर ध्यान दिया है:
जब मैं closesocket (client_socket) कहते हैं; कनेक्शन के सर्वर के साइड एंडपॉइंट पर, क्लाइंट साइड की बजाय, (या तो अदरक {सत्य, 0} या नहीं) सेट करने के साथ, लंबित पढ़ना गलत, के रूप में पूरा हो जाएगा, जो पढ़ा गया आकार न केवल = = 0, लेकिन GetLastError() भी एक त्रुटि देता है: 64, या 'ERROR_NETNAME_DELETED'। मैंने वेब पर इस बारे में बहुत कुछ खोजा है, लेकिन कुछ भी दिलचस्प नहीं मिला।
फिर मैंने खुद से पूछा: लेकिन क्या यह एक वास्तविक त्रुटि है? मेरा मतलब है, क्या यह वास्तव में एक त्रुटि माना जा सकता है?
समस्या यह है कि सर्वर की तरफ, ऑनरर() कॉलबैक कॉल किया जाएगा जब मैं closesocket (client_socket); onEof() के बजाय। तो मैंने यह सोचा:
क्या होगा, जब यह 'ERROR_NETNAME_DELETED' "त्रुटि" प्राप्त होती है, तो Err() के बजाय Eof() पर कॉल करें? क्या यह कुछ बग या अपरिभाषित व्यवहार पेश करेगा? एक अन्य महत्वपूर्ण बिंदु है कि मुझे यह सवाल पूछते बना यह है:
जब मैं इस के साथ 'ERROR_NETNAME_DELETED' पूरा होने पढ़ प्राप्त हुआ है, मैं विशेष रूप से overlapped-> आंतरिक पैरामीटर जो NTSTATUS त्रुटि हो ओवरलैप संरचना जाँच कर ली है, अंतर्निहित ड्राइवर का कोड । अगर हम NTSTATUS त्रुटि कोड [http://www.tenox.tc/links/ntstatus.html] की एक सूची देखते हैं तो हम स्पष्ट रूप से देख सकते हैं कि 'ERROR_NETNAME_DELETED' NTSTATUS 0xC000013B द्वारा उत्पन्न होता है, जो एक त्रुटि है, लेकिन इसे 'STATUS_LOCAL_DISCONNECT' कहा जाता है। खैर, यह किसी त्रुटि के लिए नाम की तरह नहीं दिखता है। ऐसा लगता है कि 'ERROR_IO_PENDING' जैसी एक त्रुटि है, लेकिन एक सही व्यवहार की स्थिति भी है।
तो ओवरप्लेड संरचना के आंतरिक पैरामीटर की जांच करने के बारे में क्या, और जब यह == को 'STATUS_LOCAL_DISCONNECT' पर कॉल करने के लिए ऑनऑफ() कॉलबैक पर कॉल किया जाता है? क्या गड़बड़ चीजें होगी?
इसके अलावा, मुझे यह कहना है कि सर्वर पक्ष से, यदि मैं कोठरी (क्लाइंट_सेट) को कॉल करने से पहले DisconnectEx() को कॉल करता हूं; मुझे वह त्रुटि नहीं मिलेगी। लेकिन क्या मैं DisconnectEx() को कॉल नहीं करना चाहता हूं? जैसे जब सर्वर बंद हो रहा है और सभी DisconnectEx() पूर्णता का इंतजार नहीं करना चाहता, लेकिन बस सभी क्लाइंट के कनेक्ट को बंद करना चाहते हैं।
@ हंस, मुझे लगता है कि उन्होंने यह वर्णन करने का एक अच्छा काम किया कि उन्हें उस त्रुटि का सामना कैसे हुआ। –