2011-03-22 10 views
6

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

हालांकि, यदि उपयोगकर्ता पहले से कनेक्ट होने पर दूसरे सर्वर पर क्लिक करता है, तो दो एक साथ कनेक्शन होते हैं।

Socket socket = new Socket(); 
socket.connect(socketAddress, connectTimeout); 

मैंने सोचा कि शायद Thread.currentThread().interrupt(); काम करेगा, लेकिन नहीं किया:

मैं इस का उपयोग कर जोड़ने रहा हूँ, और कनेक्ट() लाइन ब्लॉक है।

क्या मुझे अपने कोड को थोड़ा सा पुनर्गठन करना है ताकि यह पहला कनेक्शन बना रहा हो, लेकिन इसे सीधे बंद कर दिया जाए? या वास्तव में कनेक्ट विधि को बाधित करने का एक तरीका है।

उत्तर

2

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

यदि आप चाहते हैं कि आपके पास look at my throwaway attempt है जो ब्लॉकिंग कॉल को अवरुद्ध करने वाले थ्रेड में बाधा डालता है।

+0

जब मैं socket.close() की कोशिश है, यह कहना है कि सॉकेट रिक्त है .. लेकिन यह होना चाहिए एक वैध (कनेक्ट नहीं किए गए) सॉकेट ऑब्जेक्ट। मैं डिस्कनेक्ट() नामक विधि के अंदर एक ही रननेबल क्लास में क्लोज़() को कॉल कर रहा हूं, जिसे किसी अन्य धागे द्वारा बुलाया जाता है, यही कारण है? क्या बंद() को सॉकेट पर सीधे एक अलग धागे से बुलाया जाना चाहिए? – Matt

+0

@ मैट: कोड को देखने के बिना बताना मुश्किल होगा लेकिन पुष्टि करना चाहता था; सॉकेट वैरिएबल और इंस्टेंस वैरिएबल या एक विधि स्कॉप्ड है? क्या आप सुनिश्चित हैं कि रननेबल कार्य की 'सॉकेट' विशेषता गैर-शून्य है? यदि हां, तो क्या आप कार्य ऑब्जेक्ट में सॉकेट चर 'volatile' बनाने का प्रयास कर सकते हैं और पुनः प्रयास करें? क्या यह अभी भी असफल रहा है? –

1

क्या आप इसके बजाय गैर-अवरुद्ध सॉकेट का उपयोग कर सकते हैं? मैं जावा विशेषज्ञ का अधिक नहीं हूं, लेकिन ऐसा लगता है कि सॉकेट चैनेल उनकी गैर-अवरुद्ध सॉकेट क्लास है।

// Create a non-blocking socket and check for connections 
try { 
    // Create a non-blocking socket channel on port 80 
    SocketChannel sChannel = createSocketChannel("hostname.com", 80); 

    // Before the socket is usable, the connection must be completed 
    // by calling finishConnect(), which is non-blocking 
    while (!sChannel.finishConnect()) { 
     // Do something else 
    } 
    // Socket channel is now ready to use 
} catch (IOException e) { 
} 

यहाँ से लिया: http://www.exampledepot.com/egs/java.nio/NbClientSocket.html

जबकि पाश आप कुछ साझा सूचना है कि आप रद्द कर दिया और जमानत करने की आवश्यकता के लिए जाँच कर सकते हैं अंदर, SocketChannel बंद करने

यहाँ एक उदाहरण है जैसे तुम जाओ।

1

मैंने सुझाए गए उत्तरों की कोशिश की लेकिन मेरे लिए कुछ भी काम नहीं किया। तो मैंने जो किया वह 10 सेकंड तक मेरा कनेक्शन टाइमआउट सेट करने के बजाय, 2 सेकंड के कनेक्शन टाइमआउट के साथ पंक्ति में 5 बार कनेक्ट करने का प्रयास करता था। मेरे पास एक वैश्विक चर boolean cancelConnection घोषित किया गया है।

प्रत्येक बार टाइमआउट अपवाद फेंक दिया जाता है, तो मैं cancelConnection के मूल्य के आधार पर पाउडर को तोड़ सकता हूं या जारी रख सकता हूं।

यहाँ मैं लिख रहा हूँ एक Android एप्लिकेशन से कोड का टुकड़ा है:

try { 
    SocketAddress socketaddres = new InetSocketAddress(server.ip,server.port); 
    int max=5; 
    for (int i = 1; i<=max; i++) { 
     try { 
      socket = new Socket(); 
      socket.connect(socketaddres, 2000); 
      break; 
     } catch (Exception e) { 
      Log.d(TAG, "attempt "+i+ " failed"); 
      if (cancelConnection) { 
       Log.d(TAG, "cancelling connection"); 
       throw new Exception(); 
      } else if (i==max) { 
       throw new Exception(); 
      } 
     } 
    } 
} catch (Exception e) { 
    if (cancelConnection) { 
      // Do whatever you would do after connection was canceled. 
    } else { 
      // Do whatever you would do after connection error or timeout 
    } 
} 
संबंधित मुद्दे