2010-03-03 18 views
8

मैं नामित पाइप के बारे में सीख रहा हूँ और MSDN दस्तावेज़ से नामित पाइप क्लाइंट और सर्वर उदाहरण के साथ खेल रहा था:कैसे एक नामित पाइप क्लाइंट/सर्वर का उपयोग कर एक ग्राहक डिस्कनेक्ट पता लगाने के लिए?

Named Pipe Server

Named Pipe Client

मैं ग्राहक संशोधित तो मैं करने के लिए संदेश में टाइप कर सकते हैं कंसोल और उन्हें सर्वर पर भेजा गया है जहां यह संदेश प्रदर्शित करता है और एक जवाब वापस भेजता है। अनिवार्य रूप से मैं एक पाश जो SetNamedPipeHandleState() कॉल के बाद शुरू होता है और इससे पहले कि CloseHandle() कॉल समाप्त होता है जोड़ा (अर्थात खुले और बंद लूप के बाहर होने वाले हैं, इसलिए मैं पाश के भीतर एक ही पाइप संभाल उपयोग कर रहा हूँ)।

मेरा प्रश्न है, अगर मैं ग्राहक को मारने (यह बंद करने या कार्य प्रबंधक के माध्यम से इसे बंद कर दिया) है वहाँ सर्वर साइड के लिए किसी भी तरह से डिस्कनेक्ट पता लगाने के लिए है?

मैंने GetNamedPipeHandleState() का उपयोग करने की कोशिश की है, यह विफल होने की उम्मीद है और GetLastError() को एक कॉल ERROR_PIPE_NOT_CONNECTED वापस कर देगा, लेकिन ऐसा नहीं था। जिस तरह से इस सर्वर की स्थापना की है की मैं CompletedReadRoutine समारोह में यह कर और एक "नियंत्रित" विफलता बनाने के लिए किया था। क्या मैंने किया था सर्वर में CompletedReadRoutine पर एक ब्रेकपाइंट के साथ था,:

  1. सर्वर
  2. ग्राहक
  3. क्लाइंट के माध्यम से एक संदेश भेजा शुरू कर दिया (सर्वर यहाँ में ब्रेकप्वाइंट हिट)
  4. शुरू कर दिया
  5. ग्राहक
  6. GetNamedPipeHandleState
के माध्यम से कदम रखा मारे गए

GetNamedPipeHandleState() करने के लिए कॉल सफलता देता है पूरी तरह से मुझे GetLastError() कॉल करने के लिए कभी नहीं मिला। यह WriteFileEx जाता जब फोन यह विफल रहता है और उस बिंदु पर GetLastError के लिए एक कॉल एक ERROR_NO_DATA देता है।

पाइप फ़ंक्शंस को देखते हुए मैं कुछ भी नहीं देख सकता जो संभवतः यहां सहायता करेगा। मुझे कुछ याद आ रहा है या क्लाइंट डिस्कनेक्ट सिर्फ पता लगाने योग्य नहीं है।

एकमात्र अन्य चीज जिसे मैं सोच सकता हूं, कनेक्टिंग क्लाइंट के पिड (GetNamedPipeClientProcessId के माध्यम से) एकत्र कर रहा है और यह जांचने के लिए वॉचडॉग थ्रेड्स को कताई कर रहा है कि वे अभी भी जीवित हैं या नहीं। हालांकि, बस मेरे स्पाइडी भावना से सेट करने के बारे में सोच रहा है।

वहाँ जब नामित पाइप का उपयोग कर कट ग्राहकों का पता लगाने के लिए एक रास्ता है?

उत्तर

5

ReadFile() वापसी और त्रुटि नहीं है और GetLastError() फिर ERROR_BROKEN_PIPE लौटाएं?

+0

केवल अगर मैं क्लाइंट को सर्वर में ब्रेकपॉइंट्स का उपयोग करके बहुत सावधानी से मारता हूं तो मैं सर्वर तर्क में एक विशिष्ट पायदान पर क्लाइंट को मार सकता हूं। उदाहरण के लिए, यदि मैं क्लाइंट शुरू करता हूं और प्रारंभिक कनेक्शन के ठीक बाद इसे मारता हूं लेकिन पहली बार सर्वर ReadFileEx को कॉल करता है, तो हाँ मुझे ERROR_BROKEN_PIPE मिलता है। समस्या यह है कि सर्वर WaitForSingleObjectEx पर कॉल पर प्रतीक्षा करता है। यदि ग्राहक पक्ष नीचे चला जाता है तो यह उस पूर्ववत रूप से पाइप उदाहरण से जुड़ा हुआ नहीं है या पढ़ता है। –

+3

मुझे सच में नहीं लगता कि उन नमूने अच्छे हैं कि चीजों को कैसे करना है ... व्यक्तिगत रूप से मेरे पास हमेशा पाइप पर लंबित एक ओवरलैप्ड रीड होता है, इस तरह क्लाइंट को दूर होने पर आपको हमेशा एक अधिसूचना मिलनी चाहिए। .. –

+0

मैं आपको सुनता हूं और सहमत हूं कि मेरे पास जो उदाहरण हैं, वे नहीं हैं जो मुझे देखना चाहिए कि जिस तरह से मैं काम करने के लिए काम करना चाहता हूं। आपके सहयोग के लिए धन्यवाद। –

1

ReadFile() + GetLastError() अच्छी तरह से काम करें। यहाँ कैसे वे मैं के साथ इस्तेमाल किया जा सकता है/O पूर्णता बंदरगाहों (मेरी कार्यान्वयन अजगर + ctypes में है, लेकिन विचार स्पष्ट किया जाना चाहिए):

def connect(): 
    GetQueuedCompletionStatus() 
    receive() 

def receive(): 
    while True: 
     ret_code = ReadFile() 
     if ret_code == 0 and GetLastError() == ERROR_BROKEN_PIPE: 
      # client disconnected 
     GetQueuedCompletionStatus() 

हम एक पूरा होने के पैकेट के लिए इंतजार कर रहे हैं, और जब एक ग्राहक जोड़ता , हम मुख्य पाश पर स्विच करते हैं। मुख्य पाश में हम पाइप पढ़ते हैं और जांचते हैं कि क्लाइंट ReadFile() रिटर्न कोड और GetLastError() देखकर डिस्कनेक्ट हो गया है या नहीं। फिर फिर, हम एक पूरा पैकेट की प्रतीक्षा करेंगे।

कोई ग्राहक किसी भी चरण पर डिस्कनेक्ट कर सकता है। पूरा पैकेट कतारबद्ध किया जाएगा और हमें ERROR_BROKEN_PIPE मिलेगा।

+0

यह कौन सी प्रोग्रामिंग भाषा है? यह पाइथन की तरह थोड़ा दिखता है, लेकिन AFAIK 'winapi' सी, सी ++, सी # और केवल विजुअल बेसिक है। – wizzwizz4

+0

हां, यह पायथन है, लेकिन आप ctypes लाइब्रेरी का उपयोग करके winapi फ़ंक्शंस को कॉल कर सकते हैं। एक तंत्र जो इसे अनुमति देता है उसे एफएफआई कहा जाता है: https://en.wikipedia.org/wiki/Foreign_function_interface – wombatonfire

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

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