2010-09-02 19 views
7

मैं अपने एक्सएनए-नेटवर्कगाम के लिए यूडीपी-सॉकेट का उपयोग करना चाहता हूं। और अब मैं एक विश्वसनीय श्रोता प्रकाशित करने की कोशिश कर रहा हूं, लेकिन कुछ समस्याएं हैं।सी #: यूडीपी श्रोता थ्रेड

यदि मैं सॉकेट का उपयोग करता हूं। पुनः प्राप्त करें यह एक पैकेट तक इंतजार करेगा। यह मेरे श्रोता के लिए ठीक है। मेरे धागा इस तरह थोड़ी देर के पाश है:

while(Listen == true) 
{ 
    socket.Receive(...); 
} 

लेकिन अगर मैं (अगर मैं सुन बंद करना चाहते हैं) को गलत पर सुनो-ध्वज स्वैप, यह पिछले .Receive में फंस जाएगा()।

फिर मैंने मेथोड्स को देखा .बिनर रिसीव()। यदि एक पैकेट पहुंचा तो यह मेथोड को कॉल करेगा। लेकिन डेटा प्राप्त करने के लिए मुझे उपयोग करना होगा। EndReceive() और यही वह बिंदु है जिसमें मुझे कोई समस्या है। मैं अभी भी पैकेट के लिए सुनना चाहता हूं और एक पैकेट आने पर सुनना बंद नहीं करना चाहता हूं।

तो मैं अभी भी "रिसीविव()" के साथ अवरुद्ध संस्करण का उपयोग करता हूं। मैं सुनकर धागे को कॉल करके रद्द कर सकता हूं: Thread.abort(), लेकिन यह अच्छा नहीं है।

वर्तमान में मैं का परीक्षण करता है, तो डेटा उपलब्ध है:

while(Listen == true) 
{ 
    if(socket.Available > 0) 
    { 
     socket.Receive(...); 
    } 
} 

लेकिन मुझे लगता है यह सबसे अच्छा तरीका नहीं है ... तो शीघ्र ही अगर-खंड एक अन्य धागा socket.Receive बुला रहा है (के बाद ..) यह फिर से अनजान अटक जाएगा। क्या रद्द करने का कोई तरीका नहीं है। .. (विधि) विधि? मैंने टाइमआउट सेट करने का प्रयास किया, लेकिन अगर। बार-बार टाइमआउट, यह एक अपवाद फेंक देगा ...

मुझे एक साधारण उद-सुनना धागा चाहिए, मैं कृपा से रुक सकता हूं। :-) एमएसडीएन में मुझे एक श्रोता-उदाहरण नहीं मिला जो एक से अधिक पैकेट के लिए सुन रहा है। अन्य प्रोग्रामर को कैसे संभालते हैं?

+0

"अगर शीघ्र ही अगर-खंड के बाद एक अन्य धागा socket.Receive (..) बुला रहा है" - यह मतलब है एक से अधिक थ्रेड एक ही सॉकेट से पढ़ने देखते हैं कि लगता है? – Ragoczy

+0

नहीं, मैं ऐसा नहीं करता हूं। लेकिन यह संभव है और मैं इससे बचना चाहता हूं :-) – user437899

+1

जब आप सुनना बंद करने के लिए तैयार हों, तो सॉकेट बंद करें। अवरुद्ध 'प्राप्त करें() 'विधि' सॉकेटएक्सप्शन 'के साथ बाहर निकल जाएगी जिसे आपको पकड़ने की आवश्यकता होगी। –

उत्तर

9

Listen ध्वज को अस्थिर के रूप में चिह्नित करें, इसलिए धागे के बीच परिवर्तन दिखाई दे सकते हैं।

public volatile bool Listen{get; set;} 

अपने सूत्र में उचित अपवाद संभाल:

Thread listener = new Thread(()=> 
{ 
    while(Listen == true) 
    { 
     try 
     { 
      socket.Receive(); 
     } 
     catch(ThreadInterruptException) 
     { 
      break; // exit the while loop 
     } 
     catch(SocketException) 
     { 
      break; // exit the while loop 
     } 
    } 
}); 
listener.IsBackground = true; 
listener.Start(); 

कोड में जहां false को Listen झंडा स्विच कर रहे हैं या तो आप सॉकेट बंद करने या आप धागा बीच में:

Listen = false; 

socket.Shutdown(SocketShutdown.Both); 
socket.Close(); 
// 
// OR 
// 
listener.Interrupt(); 
1

धन्यवाद लीरिक और मैट डेविस। यह ठीक काम करता है, लेकिन क्या इसके लिए अपवादों का उपयोग करना ठीक है? मैंने सीखा है कि अगर कुछ बुरा/अप्रत्याशित होता है तो अपवाद केवल फेंक दिया जाना चाहिए। (अवरुद्ध मेथोड को रोकने के लिए इरादा है :-))

मैंने इस तरह के अपवाद को संभाला। मैं त्रुटि कोड की तलाश करता हूं और फिर लूप तोड़ता हूं।

   try 
       { 
        broadcastSocket.ReceiveFrom(returnData, ref ep); 

        //... 
       } 
       catch (SocketException ex) 
       { 
        if (ex.ErrorCode == 10004) 
        { 
         break; 
        } 
       } 

क्यों मैं

socket.Shutdown(SocketShutdown.Both); 

से पहले

socket.Close(); 

.Close जाएगा() बंद नहीं सॉकेट के साथ-साथ उपयोग करने के लिए है?

और यदि मैं फिर से सॉकेट का उपयोग करना चाहता हूं, तो क्या एक "पुनरारंभ करें" -मेथोड ओडर को एक नया सॉकेटइंस्टेशन बनाना चाहिए?

अभिवादन user437899

+0

अवरुद्ध कॉल से बाहर निकलने के लिए अपवाद का उपयोग करना बिल्कुल ठीक है, इसलिए अपवाद को डरो मत! शट डाउन भेजने और प्राप्त करने से रोकता है, लेकिन बंद सॉकेट को "बंद" कर देगा लेकिन एक सशक्त तरीके से। यदि आप सॉकेट का पुन: उपयोग करना चाहते हैं तो बंद करने के बजाय डिस्कनेक्ट को कॉल करें। – Kiril

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