2009-04-21 15 views
9

मैं जावा में थ्रेडेड यूडीपी आधारित सर्वर को कैसे कार्यान्वित कर सकता हूं?मैं जावा में थ्रेडेड यूडीपी आधारित सर्वर को कैसे कार्यान्वित कर सकता हूं?

असल में जो मैं चाहता हूं, सर्वर से कई क्लाइंट कनेक्ट करना है, और प्रत्येक क्लाइंट का अपना धागा होना चाहिए। एकमात्र समस्या यह है कि मुझे नहीं पता कि कैसे क्लाइंट सर्वर से कनेक्ट करने का प्रयास कर रहा है और इसके लिए एक नया धागा पैदा कर रहा है।

boolean listening = true; 

System.out.println("Server started."); 

while (listening) 
    new ServerThread().start(); 

इस मामले में जब तक यह स्मृति से बाहर नहीं हो जाता तब तक सर्वर नए धागे को जन्म देगा। यहाँ ServerThread (मुझे लगता है कि मैं यहाँ एक तंत्र है कि ServerThread के निर्माण रुक जाता है जब तक एक ग्राहक कनेक्ट करने के लिए कोशिश करता है की जरूरत के लिए कोड है।

public ServerThread(String name) throws IOException 
{ 
    super(name); 
    socket = new DatagramSocket(); 
} 

तो जावा प्रोग्रामिंग के पिता कृपया मदद करते हैं।

+9

यह मेरे लिए होमवर्क की तरह गंध करता है। –

+1

मुझे पता है कि यह एक पुराना क्यू है लेकिन आपने जो कुछ किया था, वह सुनने के दौरान लूप था, हर बार नया डेटाग्राम सॉकेट बना रहा था, जितना तेज़ आपका सिस्टम हो सकता था। आप पूरी तरह से स्मृति से बाहर भाग लेंगे। – garlicman

+1

यह एक अच्छा सवाल है जो निष्पादक सेवा का उपयोग कर उत्तर देने योग्य है। – JohnMerlino

उत्तर

13

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

मैंने जो रैडियस सर्वर लिखा था, वह एक ही अनुरोध था + मॉडल को दोबारा तैयार करना और प्रत्येक आने वाले पैकेट के लिए एक थ्रेड बनाया।

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

public class Server implements Runnable { 
    public void run() { 
     while (true) { 
      DatagramPacket packet = socket.receive(); 
      new Thread(new Responder(socket, packet)).start(); 
     } 
    } 
} 

public class Responder implements Runnable { 

    Socket socket = null; 
    DatagramPacket packet = null; 

    public Responder(Socket socket, DatagramPacket packet) { 
     this.socket = socket; 
     this.packet = packet; 
    } 

    public void run() { 
     byte[] data = makeResponse(); // code not shown 
     DatagramPacket response = new DatagramPacket(data, data.length, 
      packet.getAddress(), packet.getPort()); 
     socket.send(response); 
    } 
} 
+0

के बाद से प्रत्युत्तर केवल Runnable लागू करता है कि आप इसे एक धागा देने के लिए की आवश्यकता होगी।। एक निष्पादक सेवा का उपयोग हालांकि बेहतर थ्रेड प्रबंधन प्रदान करेगा। – thoughtcrimes

+0

@thoughtcrimes मुझे नहीं लगता कि 'निष्पादक सेवा' वर्ग अस्तित्व में था जब मैंने पहली बार कोड लिखा था, यह उदाहरण लिया गया था। 'थ्रेड' त्रुटि पर अच्छी जगह! – Alnitak

+0

"प्रत्येक ग्राहक के लिए कई पैकेट प्रक्रिया" के मामले में। टीसीपी लगातार इसके बाद से बेहतर है? – Sohaib

5

यूडीपी के बाद से एक कनेक्शन रहित प्रोटोकॉल है, आपको प्रत्येक कनेक्शन के लिए एक नया धागा क्यों तैयार करने की आवश्यकता है? जब आपको यूडीपी पैकेट प्राप्त होता है तो आपको प्राप्त संदेश से निपटने का ख्याल रखने के लिए एक नया धागा तैयार करना चाहिए।

यूडीपी कनेक्शन पसंद नहीं हैं टीसीपी कनेक्शन। वे सक्रिय नहीं रहते हैं और यूडीपी का डिजाइन है।

यह अगले कोड ब्लॉक जो कुछ भी इसे प्राप्त डेटा के साथ चाहता है क्या कर सकते हैं handlePacket() विधि। और कई ग्राहक एक ही यूडीपी श्रोता को कई पैकेट भेज सकते हैं। शायद यह आपकी मदद करेगा।

public void run() { 
     DatagramSocket wSocket = null; 
     DatagramPacket wPacket = null; 
     byte[] wBuffer = null; 

     try { 
      wSocket = new DatagramSocket(listenPort); 
      wBuffer = new byte[ 2048 ]; 
      wPacket = new DatagramPacket(wBuffer, wBuffer.length); 
     } catch (SocketException e) { 
      log.fatal("Could not open the socket: \n" + e.getMessage()); 
      System.exit(1); 
     } 

     while (isRunning) { 
      try { 
       wSocket.receive(wPacket); 
       handlePacket(wPacket, wBuffer); 
      } catch (Exception e) { 
       log.error(e.getMessage()); 
      } 
     } 
    } 
+0

सिर्फ उत्सुक है, लेकिन 'डब्ल्यू' उपसर्ग क्या है? हो सकता है कि मैं सी-क्षतिग्रस्त हूं लेकिन यह निश्चित रूप से एक शब्द गठबंधन int या कुछ जैसा दिखता है ... बी-) – KarlP

+0

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

+0

और मजदूर वर्ग के लिए उपसर्ग क्या है?() (नया थ्रेड (नई प्रत्युत्तर (पैकेट))) शुरू: – lelloman

3

आप Apache Mina परियोजना को देखा है? मेरा मानना ​​है कि इसके उदाहरणों में से एक भी आपको यूडीपी-आधारित सर्वर को सेटअप करने के तरीके के माध्यम से ले जाता है। यदि यह वास्तविक उत्पाद के लिए है, तो मैं स्क्रैच से अपने स्वयं के कार्यान्वयन के साथ आने की कोशिश करने की अनुशंसा नहीं करता। आप इसे पूरा करने के लिए लाइब्रेरी का उपयोग करना चाहेंगे ताकि आप पर एक थ्रेड प्रति कनेक्शन, बल्कि थ्रेड पूल का उपयोग कर सकें।

1

मुझे वास्तव में आवश्यकता नहीं दिखाई देती है।

यह एक स्कूल की बात सही है?

यदि आपको ग्राहकों का ट्रैक रखने की आवश्यकता है, तो आपके पास प्रत्येक ग्राहक का स्थानीय प्रतिनिधित्व होना चाहिए (आपके सर्वर पर क्लाइंट ऑब्जेक्ट)। यह आपको जो क्लाइंट-विशिष्ट चीजों को करने की ज़रूरत है, उसका ख्याल रख सकता है।

उस मामले में आप पता लगाने के लिए संदेश है जो क्लाइंट की ओर से भेजा गया है, में सक्षम होना चाहिए। (संदेश से जानकारी का उपयोग कर।) आप ग्राहकों को मानचित्र में रख सकते हैं।

सबसे प्रभावी तरीका मुख्य धागे में सभी को संभालने के लिए संभवतः है, जब तक कि जो कुछ भी करने की ज़रूरत नहीं है, बाहरी घटनाओं के इंतजार में "अवरुद्ध" हो सकता है (या यदि कुछ चीजें जो होने वाली हैं तो उन्हें लंबा समय लग सकता है और कुछ एक बहुत छोटा।)

public class Client { 

    public void handleMessage(Message m) { 
    // do stuff here. 
    } 

} 

क्लाइंट ऑब्जेक्ट शायद संभाल में मैसेज() में एक नया धागा शुरू कर सकता है।

आपको एकाधिक सर्वर थ्रेड शुरू नहीं करना चाहिए।

सर्वर धागा कर सकते हैं:

while(running) { 
    socket.receive(DatagramPacket p); 
    client = figureOutClient(p); 
    client.handleMessage(p); 
} 

अगर कोई ग्राहक-विशिष्ट बातें एक सूत्र में, के बारे में परवाह सिर्फ संदेशों को पढ़ने और उन्हें संभाल के रूप में वे आने के लिए कर रहे हैं।

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

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