2010-06-12 17 views
5

चल रहा है, तो मूल रूप से मैं एक रॉक ठोस सर्वर बनाना चाहता हूं।जब सर्वरस्केट IOException फेंकता है और सर्वर को

while (keepRunning.get()) { 
    try { 
     Socket clientSocket = serverSocket.accept(); 

     ... spawn a new thread to handle the client ... 
    } catch (IOException e) { 
     e.printStackTrace(); 
     // NOW WHAT? 
    } 
} 

आईओएक्सप्शन ब्लॉक में, क्या करना है? क्या सर्वर सॉकेट गलती पर है ताकि इसे फिर से बनाया जा सके? उदाहरण के लिए कुछ ही सेकंड प्रतीक्षा करें और फिर

serverSocket = ServerSocketFactory.getDefault().createServerSocket(MY_PORT); 

लेकिन अगर सर्वर सॉकेट अभी भी ठीक है, तो यह एक दया इसे बंद करें और सब पहले से स्वीकार किए जाते हैं कनेक्शन है कि अभी भी संवाद कर रहे हैं को मारने के लिए है।

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

while (keepRunning.get()) { 
    try { 
     Socket clientSocket = serverSocket.accept(); 

     ... spawn a new thread to handle the client ... 
     bindExceptionCounter = 0; 
    } catch (IOException e) { 
     e.printStackTrace(); 

     recreateServerSocket(); 
    } 
} 

private void recreateServerSocket() { 
    while (keepRunning) { 
     try { 
      logger.info("Try to re-create Server Socket"); 
      ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(RateTableServer.RATE_EVENT_SERVER_PORT); 

      // No exception thrown, then use the new socket. 
      serverSocket = socket; 
      break; 
     } catch (BindException e) { 
      logger.info("BindException indicates that the server socket is still good.", e); 
      bindExceptionCounter++; 

      if (bindExceptionCounter < 5) { 
       break; 
      } 
     } catch (IOException e) { 
      logger.warn("Problem to re-create Server Socket", e); 
      e.printStackTrace(); 

      try { 
       Thread.sleep(30000); 
      } catch (InterruptedException ie) { 
       logger.warn(ie); 
      } 
     } 
    } 
}  

उत्तर

4

यदि संदेह है, तो आप उसी पोर्ट का उपयोग कर सर्वर सॉकेट को फिर से बनाने का प्रयास कर सकते हैं। यदि सॉकेट बंद कर दिया गया है, तो सृजन सफल हो जाएगा और आप नए कनेक्शन को संसाधित करना जारी रख सकते हैं। पुराने कनेक्शन चले गए हैं, लेकिन सॉकेट बंद होने के बाद से यह आपके नियंत्रण से बाहर है। यदि सॉकेट बंद नहीं किया गया था, तो एक नया उदाहरण बनाना विफल हो जाएगा क्योंकि बंदरगाह अभी भी उपयोग में है, जिसे आप केवल अनदेखा कर सकते हैं - यानी वर्तमान सर्वर सॉकेट संदर्भ को प्रतिस्थापित न करें।

सामान्य रूप से, ग्राहकों को यह भी मानना ​​चाहिए कि कनेक्शन टूटा जाएगा और यह कनेक्शन आवश्यक है। दूसरे शब्दों में, यह केवल सर्वर नहीं है जो मजबूत होना चाहिए - ग्राहकों को कनेक्शन त्रुटियों की भी उम्मीद करनी चाहिए और पुनः कनेक्ट करना चाहिए।

+0

यदि कोई नया सर्वर सॉकेट बना रहा है, जो BindException के साथ विफल रहता है - इसका मतलब यह होगा कि यह 100% सुनिश्चित है कि पुराने सर्वर सॉकेट पूरी तरह से ठीक है? – s5804

+0

मैं निश्चित रूप से "हाँ" नहीं कह सकता, लेकिन आम तौर पर मैं इसे मानता हूं। मैं एक रक्षात्मक रणनीति का भी उपयोग करूंगा। जैसे यदि आपको स्वीकार करने वाले असफलताओं की एक्स संख्या मिलती है, तो आप किसी भी तरह से सर्वर सॉकेट को तोड़ सकते हैं, और सर्वर सॉकेट को बंद करना चुन सकते हैं। – mdma

1

सुनिश्चित करें कि आप अलग-अलग IOException एस के बीच अंतर कर सकते हैं। क्या यह कनेक्शन बनाने पर अपवाद है? एक कनेक्शन पहले ही स्थापित हो जाने पर यह एक अपवाद है?

आपके द्वारा दिया गया एकमात्र कोड accept() आईएनजी के लिए है। आम तौर पर, IOException आमतौर पर भौतिक नेटवर्क पर किसी भी परत पर एक त्रुटि का मतलब है।

शायद सबसे अच्छा फ़ॉलबैक व्यवहार जिसे आप कार्यान्वित कर सकते हैं वह निश्चित समय क्वांटम की प्रतीक्षा करना है, और फिर पुन: कनेक्ट करने का प्रयास करें। मान लीजिए कि आप संभवतः फिर से कनेक्ट नहीं कर पाएंगे, क्योंकि आपने अस्थायी अवधि से अधिक के लिए नेटवर्क कनेक्शन खो दिया है। सुनिश्चित करें कि आप इसे सुंदर तरीके से संभाल लें। जैसा कि @mdma का उल्लेख है, यह आपके ग्राहकों द्वारा भी समर्थित होना चाहिए।

+0

पुन: कनेक्ट करें - आपका मतलब है कि सर्वर सॉकेट फिर से बनाएं? – s5804

+0

यदि आप सॉकेट खो देते हैं तो हाँ ... –

1

यदि सर्वर सॉकेट बंद है (आपके द्वारा) या आप संसाधनों से बाहर निकलते हैं, तो आप एक IOException स्वीकार() पर प्राप्त कर सकते हैं। फ़ाइल हैंडल। किसी भी तरह से, आप इसके बारे में ज्यादा कुछ नहीं कर सकते हैं। यदि सर्वर सॉकेट बंद है (आप इसके लिए परीक्षण कर सकते हैं) तो शायद आपके पास ऐसा करने का एक अच्छा कारण था। यदि आप संसाधनों से बाहर हो जाते हैं, तो आपको या तो अपनी संसाधन सीमा में वृद्धि करनी होगी, जिसके लिए आपके आवेदन को पुनरारंभ करना आवश्यक है, या आपके पास संसाधन रिसाव है।

+0

सॉकेट बंद होने पर परीक्षण कैसे करें? मैंने सोचा कि serverocket.isClosed() हमेशा झूठी वापसी करता है, क्योंकि उच्च परत निम्न स्तरों से अधिसूचित नहीं होती है। क्या ये सही है? – s5804

1

लेकिन अगर सर्वर सॉकेट अभी भी ठीक है, तो यह एक दया इसे बंद करना और सब को मार पहले से कनेक्शन है कि अभी भी संवाद कर रहे हैं स्वीकार कर लिया है।

कृपया ध्यान दें कि सर्वर सॉकेट बंद करने से पहले स्वीकृत कनेक्शन बंद नहीं होंगे। जैसे ही एक कनेक्शन स्वीकार कर लिया गया है, यह एक अलग बंदरगाह पर एक अलग, आनंदमय जीवन जीता है।

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