2010-04-23 13 views
12

मैं एक सॉकेट से फिर से कनेक्ट करने का प्रयास कर रहा हूं जिसे मैंने डिस्कनेक्ट किया है लेकिन यह किसी कारण से इसकी अनुमति नहीं देगा, भले ही मैंने "reuseSocket" तर्क के साथ डिस्कनेक्ट विधि को सही कहा है।.NET में सॉकेट का पुन: उपयोग कैसे करें?

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
_socket.Connect(ipAddress, port); 
//...receive data 
_socket.Disconnect(true); //reuseSocket = true 
//...wait 
_socket.Connect(ipAddress, port); //throws an InvalidOperationException: 

एक बार सॉकेट डिस्कनेक्ट किया गया है, आप केवल फिर से एसिंक्रोनस रूप से, और केवल एक अलग समाप्ति बिंदु को फिर से कनेक्ट कर सकते हैं। BeginConnect को उस थ्रेड पर कॉल किया जाना चाहिए जो ऑपरेशन पूरा होने तक से बाहर नहीं निकलेगा।

मैं क्या गलत कर रहा हूं?

+0

शायद, आपको सॉकेट का पुन: उपयोग नहीं करना चाहिए और बस एक नया बनाना चाहिए। 'डिस्कनेक्ट' को कभी भी कॉल न करें, इसे इसके बजाय 'उपयोग' में लपेटें। साथ ही, 'शटडाउन' पर कॉल करें। – usr

उत्तर

3

Socket.Disconnect के लिए एमएसडीएन दस्तावेज पढ़ने के बाद मैंने कुछ ऐसा देखा जो आपकी समस्या का कारण बन सकता है।

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

DontLinger सॉकेट विकल्प सेट करने का प्रयास करें और एक 0 टाइमआउट तैयार करें या Shutdown का उपयोग करने से पहले आप डिस्कनेक्ट कहते हैं।

+1

मजेदार बात यह है कि ऐसी कोई संपत्ति या विधि नहीं है जिसे 'डोंटलिंगर सॉकेट' कहा जाता है। इसकी सबसे नज़दीकी चीज 'लिंजरस्टेट' नामक एक संपत्ति है।आप यद्यपि 'LingerOption' को तत्काल चालू कर सकते हैं और इसे सेट कर सकते हैं, लेकिन अगर आप 'डिस्कनेक्ट' कॉल करने के बाद पुनः कनेक्ट करने का प्रयास करते हैं तो इससे कोई फर्क नहीं पड़ता है। और यदि आप 'बंद करें' कहते हैं तो आप सॉकेट का पुन: उपयोग नहीं कर सकते क्योंकि यह सॉकेट का निपटान करेगा। –

+0

वहां एक जगह खो गई थी, यह दो शब्द "डोंटलिंगर" और "सॉकेट" होना चाहिए था। वाक्यांश के लिए एक बेहतर तरीका है कि वाक्य * "... शटडाउन को बुला रहा है, आप [सॉकेटऑप्शन] (http://msdn.microsoft.com/en-us/library/e160993d.aspx) सेट कर सकते हैं [डोंटलिंगर] (http : //msdn.microsoft.com/en-us/library/system.net.sockets.socketoptionname.aspx) को गलत करने के लिए और एक nonzero निर्दिष्ट करें ... "* –

+0

@ScottChamberlain विधिवत ध्यान दिया। – James

0
MSDN से

:

// Release the socket. 
client.Shutdown(SocketShutdown.Both); 

client.Disconnect(true); 
if (client.Connected) 
    Console.WriteLine("We're still connnected"); 
else 
    Console.WriteLine("We're disconnected"); 

आप एक कनेक्शन उन्मुख प्रोटोकॉल का उपयोग कर रहे हैं, तो आप सॉकेट बंद करने के लिए इस विधि का उपयोग कर सकते हैं। यह विधि कनेक्शन समाप्त करती है और कनेक्ट की गई संपत्ति को गलत पर सेट करती है। हालांकि, अगर पुन: उपयोग सॉकेट सत्य है, तो आप सॉकेट का पुन: उपयोग कर सकते हैं।

यह सुनिश्चित करने के लिए कि सॉकेट बंद होने से पहले सभी डेटा भेज और प्राप्त किया जाता है, आपको डिस्कनेक्ट विधि को कॉल करने से पहले शटडाउन को कॉल करना चाहिए।

Socket.Shutdown विधि तब तक प्रतीक्षा करता है जब तक बफर में सभी डेटा भेजा या प्राप्त नहीं किया जाता है। हालांकि, अगर हम केवल अदरक विकल्प सेट करते हैं, तो कुछ टाइमआउट अंतराल के बाद सॉकेट बंद हो जाएगा।

+0

कोशिश की, काम नहीं करता है। –

+1

@ हरमन: मुझे लगता है कि सॉकेट के लिए "पुनः उपयोग करने योग्य" होने के लिए आपको कुछ सेकंड (टाइमआउट) का इंतजार करना होगा, आप अपनी सॉकेट को थ्रेड में डालने का प्रयास कर सकते हैं - रीट्रीज़ के लिए ... बस सोच रहा है; 'सुन्दर शूडाउन' के बारे में और पढ़ें, http://msdn.microsoft.com/en-us/library/ms738547(VS.85).aspx –

+0

नोट: 'क्लाइंट। कनेक्टेड 'को कनेक्शन स्थिति के रूप में परिभाषित किया गया है सबसे हालिया 'भेजें' या 'प्राप्त करें', वर्तमान स्थिति नहीं। और चूंकि आपने अभी 'डिस्कनेक्ट' कहा है, इसलिए संदेश होना चाहिए "हम जुड़े हुए थे।" और '" हम जुड़े नहीं थे "। –

4

आप इस

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, True) 

तरह सॉकेट विकल्प सेट कर सकते यह काम नहीं करता है, तो कुछ अन्य विकल्पों

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false) 
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True) 
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500) 
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, Timeout) 
1

आप डिस्कनेक्ट के बाद और कनेक्ट करने से पहले इस लाइन को जोड़ने की कोशिश की कोशिश?

client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
संबंधित मुद्दे