الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سؤال فى ال java , MultiThread , Nwetwork Programming

بدأه m_adel82 في 6 مارس 2012 · 4 رد · 1,155 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم..

انا بعمل chatting program و عندى مشكله واقعه فيها واتمنى المساعده:

البرنامج mutlithread اى client هيتم التعامل معاه فى thread خاصه بيه وعندى فى واجهه ال server فيها start button و stop button , لما يتم الضغط على stop button يقفل ال server ويبعت رسالة لكل ال client ان ال server

كود ال start button

 public void openServerSocket()throws IOException{
       boolean running  = true;
       serverSocket = new ServerSocket(2025);
       clientSockets = new ArrayList();
       while(running){
            try {
               Executor service = Executors.newCachedThreadPool(); 
               clientSocket = serverSocket.accept();


                service.execute(new ChattingProtocolWorker(clientSocket));
                System.out.println("Connection Established");
                /*clientThread = new Thread(new ChattingProtocolWorker(clientSocket));
                clientThread.setName("client_"+counter);
                clientThread.start();*/



            } catch (SocketException ex1) {
                running = false;
            }
        }

    }

كو] ال stop button

  public void closeServerSocket() {

        if(serverSocket !=null && clientSocket != null){
            try {

                serverSocket.close();
                clientSocket.close();

            } catch (SocketException ex) {
              System.out.println(ex);

              System.out.println("Connection Tarminated");
            }
             catch(IOException ex){

             }


        }
    }

h

اما بالنسبه لل client انا الى بعملوا انى بعمل check عن طريق (socket.inputstream ==-1) وفى الحاله ديه بعرف ان ال socket تم غلقه من ناحية ال server

ولو افترضت انى عندى two clients عملو connect على ال server وانا دوست على stop button واحد بس من ال two client بيحصل فيه ان (socket.inputstream ) بترجع 1- والتانى ﻷ..وبتالى واحد بس من ال client بيظهر عندو رساله ان ال server تم غلقه..

كود ال client

private void handleCheckServer() throws Exception , IOException,SocketException{
        boolean flag = true;
        ObjectInputStream objIn = new ObjectInputStream(in);
        while(flag){

                 if(!(in.read() >= 0)){
                    flag = false;
                    clientOperations.closeSocket();
                    throw new Exception("Server Dropped");   
            }

        }
    }

فى ناحية ال server لما بنده على (socket.close ) ليه thread من الى بتخدم احد ال client بتدرك ان حصل close وبتالى ال client بتعها بيستقبل 1- على inputstream اما باقلى ال thread ﻷ..

شكراا

تم تعديل هذه المشاركة بواسطة m_adel82 في 6 مارس 2012 في 18:44

#2

قم بتشغيل الخدمة Service مرة واحدة فقط، وليس كل مرة :

Executor service = Executors.newCachedThreadPool();

انشيء هذا السطر قبل الحلقة اللانهائية والا فسوف تنشي Cached Pool لا نهائي..

عند انهاء السيرفر عليك باطفاء الخدمة shutdown (حتى لا تستقبل أي طلب أخر ويتم وضعه على الصف ) أو استخدم shutdownNow والذي سيقوم بنفس المهمة بالاضافة الى محاولة اطفاء اي كلاينت thread في الصف والتي تعمل أيضاً،، ثم اتبعها ب waitTermination حتى ينتظر الcurrent thread أن تنتهي هذه الكلاينت أو أن تنتهي الفترة الزمنية ,,

وهذا الأمر عليك بتحديده ، مالذي تريده أن يحصل وقت اغلاق السيرفر ، انتظار الكلاينت الذي يعمل حتى ينتهي ثم يتم الاغلاق بعدها، أو اجبار الكلاينت الذي يعمل بقطع مهتمه ,, في حالة الأخيرة عليك بتزويد كود الكلاينت بطريقة لالغاء عمله ، سواء كانت الفحص المستمر على boolean والتي سيقوم السيرفر عند الاغلاق بارسال رسالة لتغيير القيمة هذه للكلاينت،، أو الفحص المستمر ب Interrupted وهنا سوف يكون الكلاينت قابلين للInterruption وحينها ارسل أي رسالة متفق عليها من السيرفر يعرفها الكلاينت وعند وصولها قم بعمل Thread.currentThread.interrupt للكلاينت,, على كل عليك التأكد بعدها من اغلاق كل الresources المفتوحة ,,

انصحك بقرائة :

Java Concurrency In Practice

أيضاً هناك مكتبة لأحد الأعضاء Dr.Robot اسمها Network Services موجودة هنا، أعتقد أنها تخفي تفاصيل الكثير من هذه الأمر بخلف API معينة ،، يمكنك النظر للكود أو استخدامها للفائدة ,,

بالتوفيق،

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#3

شكرا على الرد..

انا كل ما افعله عند ال client انى بفحص الشرط !(in.read() >= 0) لانه فى حالة اغلاق ال socket م ال server سيقوم بارسال القيمه 1- وفى هذه الحاله اقوم بانهاء عمل ال client :

 private void handleCheckServer() throws Exception , IOException,SocketException{
        boolean flag = true;

        while(flag){

                 if(!(in.read() >= 0)){
                    flag = false;
                    clientOperations.closeSocket();
                    throw new Exception("Server Dropped");   
            }

        }
    }

ولكن اذا تم اتصال اكتر من client فان هذه العمليه فقط تتم على اخر متصل ولا تتم على باقى ال client

#4

بشكل عام عندما يرسل السيرفر رسالة يفهمها الكلاينت للايقاف ، يقوم عندها الكلاينت باغلاق السوكت ,, وليس السيرفر:

public void closeServerSocket() {

        if(serverSocket !=null && clientSocket != null){
            try {

                serverSocket.close();
                clientSocket.close();

            } catch (SocketException ex) {
              System.out.println(ex);

              System.out.println("Connection Tarminated");
            }
             catch(IOException ex){

             }


        }
    }

ما قمت به هو اغلاق أخر client socket ،، لذلك لا تقوم باغلاقه من هنا، بل من داخل كل كلاينت بعد معرفته أنه حان وقت الخروج,,

أرجوا أن تكون الفكرة قد وضحت،،

بالتوفيق،

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#5

بسم الله والصلاة والسلام على رسول الله ..

اولا : لكي يعرف الكلاينت Client بأن السيرفر تم إطفائه وأفضل طريقة لذلك هو التالي :

1- في حالة إتصال ال Client بالسيرفر يقوم السيرفر بتشغيل Thread ووضيفته الاساسيه إرسال رساله Byte الى ال Client كل مده معينة ولتكن ( 10 Sec ) ومن خلالها يعرف ال Client بأن السيرفر موجود .

2- في حال قبول الاتصال من السيرفر يتم تشغيل Thread ووضيفته إرسال رساله الى السيرفر Server كل مدة معينة ومن خلالها يقوم السيرفر بمعرفة أن ال Client موجود .

لابد من وضع soSocketTimeOut قي السيرفر وال Client . ووضع مده معينة .

ووضع Exception Socket time out داخل run . ل Thread .

وأخيرا في حال عدم استقبال رساله من السيرفر يتأكد ال Client بأنه أمام أحد أمرين , إما السيرفر مطفي أو بأن الاتصال بالانترنت إنقطع .

وبالنسبه للسيرفر في حالة عدم استقباله رساله من Client يعرف بأن أمر ما حصل لل Client ويقوم بحذفه من arrayList إذا كان جميع ال Client داخل arrayList ,

الموضع كبير جدا وأتمنى أعطيتك لمحة عنه .

1

مواضيع مشابهة