2011-07-19 8 views
5

मैं TcpClient.BeginConnect/TcpClient.EndConnect कॉम्बो के साथ अपने सर्वर से कनेक्ट करने का प्रयास कर रहा हूं। हालांकि, कुछ चीजें काम नहीं करतीं जैसी उन्हें चाहिए।टीसीपी क्लाइंट.एंडकनेक्ट सॉकेट बंद होने पर NullReferenceException फेंकता है

परिदृश्य इस प्रकार है:

  • TcpClient.BeginConnect
  • सर्वर से कॉल जानबूझकर ऑफ़लाइन (परीक्षण प्रयोजनों के लिए) है - इस प्रकार का कोई संबंध नहीं बनाया जा सकता है।
  • मैं बंद आवेदन
  • TcpClient कनेक्शन कॉलबैक विधि दिया IAsyncResult
  • NullReferenceException साथ दे रही है क्या होता है TcpClient.EndConnect विधि के लिए IAsyncResult
  • कॉल (client.Close() प्रक्रिया है जिसके closes the socket which in turn stops the async operation में बुलाया जाता है) EndConnect पर होता है ()
  • चूंकि अंतिम रूप (विंडो) बंद था, ऐप से बाहर निकलना चाहिए - हालांकि यह नहीं करता टी, कम से कम BeginConnect ऑपरेशन पूरा नहीं होता है (जो अजीब है, क्योंकि कॉलबैक पहले से ही कॉल किया जा चुका है)।

exception

यहाँ क्या होता है कि एक NullReferenceException पकड़ा जाता है। जैसा कि आप ऊपर की तस्वीर से देख सकते हैं, न तो client और न ही arnull हैं। समस्या यह है कि MSDN documentation for the EndConnect उस मामले का उल्लेख नहीं करता है जिसमें इस अपवाद को फेंक दिया गया है।

तो मूल रूप से, मुझे नहीं पता कि क्या हो रहा है। समस्या यह है कि मुझे ऐप को बंद करने की प्रतीक्षा करने के लिए मजबूर होना पड़ता है (जैसे कनेक्शन ऑपरेशन अभी भी टाइमआउट के लिए इंतजार कर रहा है)। यदि कोई सर्वर ऑनलाइन है, तो यह ठीक से कनेक्ट और डिस्कनेक्ट हो जाता है।

क्याNullReferenceExceptionइस संदर्भ में मतलब है? कनेक्शन स्थापित नहीं होने पर आवेदन बंद करने के लिए BeginConnect ऑपरेशन से कैसे बचें?


अतिरिक्त नोट्स (टिप्पणी में अनुरोध किया):

public void Connect() 
{ 
    try 
    { 
     lock (connectionAccess) 
     { 
      if (State.IsConnectable()) 
      { 
       // Create a client 
       client = new TcpClient(); 
       client.LingerState = new LingerOption(false, 0); 
       client.NoDelay = true; 

       State = CommunicationState.Connecting; 

       client.BeginConnect(address, port, onTcpClientConnectionEstablished, null); 
      } 
      else 
      { 
       // Ignore connecting request if a connection is in a state that is not connectable 
      } 
     } 
    } 
    catch 
    { 
     Close(true); 
    } 
} 

इसके अलावा बंद विधि:

यहाँ ग्राहक (क्लाइंट एक सदस्य चर रहा है बनाने के लिए कोड है:

public void Close(bool causedByError) 
{ 
    lock (connectionAccess) 
    { 
     // Close the stream 
     if (clientStream != null) 
      clientStream.Close(); 

     // Close the gateway 
     if (client != null) 
      client.Close(); 

     // Empty the mailboxes 
     incomingMailbox.Clear(); 
     outgoingMailbox.Clear(); 

     State = causedByError ? CommunicationState.CommunicationError : CommunicationState.Disconnected; 
    } 
} 
+0

InnerException क्या शून्य था के बारे में कोई अधिक जानकारी दे रहा है? – Tremmors

+0

@Tremmors नहीं। InnerException शून्य है। StackTrace से भी कोई मदद नहीं (onTcpClientConnectionEstablished> EndConnect)। :( –

+0

हाँ, स्पष्ट रूप से एक रूपरेखा बग। मामले कि TcpClient() EndConnect से पहले बंद कर दिया है कहा जाता है यह ObjectDisposedException फेंक माना जाता है में। मैं बजाय पहले एक या दो बार NullReferenceException पाने के लिए लग रहे हैं, तो यह ObjectDisposedException फेंकने शुरू कर देंगे जैसा कि अपेक्षित है। मेरा सुझाव है कि आप इसे उसी तरह संभालें जैसा कि आप ऑब्जेक्ट डिस्प्लेएक्सप्शन (यानी "कनेक्शन का समय समाप्त/असफल/जो भी अन्य कारण आपने बंद किया था)(), हालांकि, मुझे नहीं पता कि कोई संसाधन लीक हो सकता है या नहीं यहां से एंडकनेक्ट() पूरा नहीं हो रहा है। शायद जीसी के साथ सौदा नहीं कर सकता है। :) – Tom

उत्तर

0

मुझे एक ही त्रुटि थी और इस कोड का उपयोग कर समाप्त हो गया। मुझे यकीन नहीं है कि यह IASyncResult इंटरफ़ेस के साथ होगा, लेकिन इस चेक को चलाने के लिए एक समान तरीका हो सकता है। मुझे लगता है कि आपका ar.AsyncState == शून्य, तो शायद वहां से शुरू करने का प्रयास करें, यानी जब आप ठीक से कनेक्ट करते हैं तो यह शून्य है?

private void connConnectCompleted(AsyncCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    { 
     // Something didn't work...abort captain 
     CloseSocket(); 
     Console.WriteLine(this.GetType().ToString() + @":Error connecting socket:" + e.Error.Message); 
     return; 
    } 
    // Do stuff with your connection 
} 

संपादित करें: माफ करना, मैं मैं पोस्ट नहीं किया था कि मेरी AsyncCompletedEventArgs उत्पन्न है, जो तुम क्या कर रहे से अधिक संबंधित है एहसास नहीं था। आप देखेंगे कि मैं ar.AsyncState के रूप में क्यों सोच रहा था।

private void OnConnect(IAsyncResult asyncResult) 
{ 
    if (OnConnectCompleted == null) return; // Check whether something is using this wrapper 
    AsyncCompletedEventArgs args; 
    try 
    { 
     Socket outSocket = (Socket) asyncResult.AsyncState; 

     // Complete connection 
     outSocket.EndConnect(asyncResult); 

     args = new AsyncCompletedEventArgs(null); 
     OnConnectCompleted(this, args); 
    } 
    catch (Exception e) 
    { 
     args = new AsyncCompletedEventArgs(e.Message); 
     OnConnectCompleted(this, args); 
    } 
} 
+0

AsyncState का उपयोग कुछ कस्टम डेटा को कॉलबैक विधि में पास करने के लिए किया जाता है। मेरे पास ऐसी ज़रूरत नहीं है इसलिए यही शून्य है। यह एक त्रुटि उत्पन्न नहीं कर सकता है। मैं आपका उदाहरण नहीं समझता (यह अपूर्ण है)। IAsyncResult में कोई त्रुटि नहीं है, और मुझे लगता है कि आपको CloseSocket() विधि के लिए कोड प्रदान करना चाहिए क्योंकि यह आपकी स्वयं की कस्टम विधि है। ओथर्विस, मुझे नहीं पता कि आपका कोड उदाहरण सहायक कैसे हो सकता है। –

+0

CloseSocket() प्रोग्राम के किसी भी अन्य भाग को सूचित करने के लिए बस कुछ घटनाओं को निकाल देता है, फिर सॉकेट पर .लोस() चलाता है। – themartinmcfly

1

NullReferenceException शायद अशक्त जा रहा है TcpClient.Client के कारण है।

आप TcpClient.BeginConnect के लिए MSDN Example का पालन करें और राज्य वस्तु के रूप में TcpClient वस्तु पारित करने के लिए थे, तो:

private void onConnEst(IAsyncResult ar) 
{ 
     try 
     { 
      TcpClient client = (TcpClient)ar.AsyncState; 
      if(client!=null && client.Client!=null) 
      { 
       client.EndConnect(ar); 
      } 
     } 
     catch(Exception ex){...} 
} 

इस मामले में जब Close() कॉलबैक से पहले कहा जाता है संभाल चाहिए।

वापस अपनी समस्या के लिए जा रहे हैं - कितनी देर तक यह अंततः पास आवेदन के लिए लगेगा?

+0

आपने ar.AsyncResult क्यों डाला? क्या आपका मतलब ar.AsyncState था? वैसे भी, मेरा ग्राहक एक निजी सदस्य है इसलिए मुझे इसे एसिंक विधि में पास करने की आवश्यकता नहीं है। मैं वर्तमान में अक्षम हूं (यानी काम पर नहीं) यह जांचने के लिए कि क्या TcpClient.Client शून्य है। हालांकि, मेरी याददाश्त और पिछले अनुभव के आधार पर, यदि मैं क्लाइंट को कॉल नहीं करता हूं। जब मैं इसे बंद करने का प्रयास करता हूं तो एप्लिकेशन को कनेक्ट करें अभी भी लटकता है। यह आमतौर पर कनेक्टिंग टाइमआउट (~ 20s) जैसा ही रहता है। और यदि मैं कनेक्शन प्रयास के दौरान ऐप बंद नहीं करता हूं, तो एक ही समय के बाद BeginConnect विफल हो जाएगा। –

+0

ओह - आप सही हैं, 'ar.AsycResult'' ar.AsyncState' होना चाहिए। बदलावों को प्रतिबिंबित करने के लिए संपादित किया गया पोस्ट। – zrc210

+0

क्या आप पोस्ट कर सकते हैं कि आप टीसीपी क्लाइंट का निर्माण कैसे कर रहे हैं, और आपका BeginConnect? शुरू करने से पहले क्या आप सॉकेट को बांधते हैं? इसके अलावा, यह महत्वपूर्ण नहीं है, लेकिन क्या नेट फ्रेमवर्क आप उपयोग कर रहे हैं? – zrc210

1

यह स्पष्ट रूप से TcpClient वर्ग के भीतर एक बग। मैंने इसका सामना भी किया है। TcpClient.Dispose क्लाइंट फ़ील्ड को शून्य पर सेट कर सकता है लेकिन EndConnect इसकी अपेक्षा नहीं करता है।

+2

एसओ में आपका स्वागत है! आप इस प्रश्न के साथ आने वाले अन्य लोगों के लिए अपने उत्तर को और अधिक गहन बनाने के लिए बग के ब्योरे पर थोड़ी अधिक जानकारी देने पर विचार करना चाहेंगे। –

0

यह a know bug है।

आप के बजाय 'NullReferenceException' के 'ObjectDisposedException' प्राप्त किया जाना चाहिए।