Сокет чата Java не показывает сообщения после добавления отправителя файла - PullRequest
0 голосов
/ 11 сентября 2011

Я написал чат-клиент, который работал нормально, пока я не решил добавить какую-нибудь вещь, отправляющую файлы, которая должна отправлять файл с клиента на сервер. После того, как я добавил строки для отправителя файла, он больше не показывает сообщения.

Думаю, проблема в том, что в run () есть два оператора try.

   public void run(){

    InputStream input = null;

    try{
        input = socket.getInputStream();
        BufferedReader inReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        //Citeste calea fisierului
        String filename = inReader.readLine();
        if(filename.equals("")){
            //Trimit status READY la client
            outReader.write("READY\n");
            outReader.flush();
        }

        FileOutputStream wr = new FileOutputStream(new File("C://tmp/"+filename));
        byte[] buffer = new byte[socket.getReceiveBufferSize()];
        int bytesReceived = 0;
        while((bytesReceived = input.read(buffer)) > 0){
            wr.write(buffer,0,bytesReceived);
        }

    }

    catch(IOException e){
        Logger.getLogger(ConectareClient.class.getName()).log(Level.SEVERE,null,e);
    }

    try{
        //Inregistreaza firul curent in listaObiecte
        listaObiecte.addElement(this);

        System.out.println("\n Fir de executie nou");
        System.out.println(this.toString());
        System.out.println(listaObiecte.toString());

        //Bucla
        while(true){
            //Se citeste mesajul din fluxul de intrare trimis de client
            String mesaj = fluxIntrare.readUTF();
            //Se transmite mesajul catre toti clientii conectati
            transmite(mesaj);
        }
    }
  //Tratare exceptie conexiune 
  catch (IOException e){
      e.printStackTrace();
  }
  finally{
        //Stergere fir curent din listaObiecte
        listaObiecte.removeElement(this);

        System.out.println("\n Fir de executie inchis");
        System.out.println(this.toString());
        System.out.println(listaObiecte.toString());

        try{
            //Inchidere socket
            socket.close();
            input.close();
        }
        //Tratare exceptie conexiune 
        catch (IOException e){
            e.printStackTrace();
        }    
  }  
}

    private static void transmite(String mesaj){
    //Enumerare generata de lista firelor de executie
    Enumeration enm = listaObiecte.elements();

    //Cat timp mai sunt elemente in enumerare
    while(enm.hasMoreElements()){
        //Se initializeaza cu null referinta firului curent
        ConectareClient firDestinatie = null;

        //Se protejeaza vectorul firelor de acces simultan
        synchronized(listaObiecte){
            //Se memoreaza referinta catre firul curent
            firDestinatie = (ConectareClient) enm.nextElement();
        }
    //Referinta valida
        if(firDestinatie != null){
            try{
                //Se protejeaza fluxul de iesire de acces simultan
                synchronized(firDestinatie.fluxIesire){
                    //Scriere mesaj in flux de iesire
                    firDestinatie.fluxIesire.writeUTF(mesaj);
                }
                //Mesajul este transmis
                firDestinatie.fluxIesire.flush();
            }
            catch(IOException e){
                firDestinatie.stop();
            }
        }
    }       
}

Ответы [ 2 ]

1 голос
/ 11 сентября 2011

Я скачал и попробовал ваш код.Короче говоря, ваша проблема в тупиковой ситуации.У вас есть два потока, один на стороне сервера и один на стороне клиента, каждый из которых ожидает, пока другой что-то сделает, чтобы первый поток мог продолжить работу.

Более подробно, вот что случилось:

  • класс ClientChat отправляет имя файла на сервер в строке 260, а затем ожидает, пока сервер отправит что-то обратно (строка с «ГОТОВ»), прежде чем он продолжит работу с фактическимотправка файла

  • с другой стороны, класс ConectareClient останавливается на строке 38, ожидает, что что-то будет отправлено от клиента, прежде чем продолжить (и отправляет сообщение о состоянии «ГОТОВ», которое, в свою очередь,клиент ждет).

Мой тебе совет такой:

Это очень похоже на домашнее задание, которое тебе дал какой-то пыльный старый профессор :)И, похоже, парень дал это вам, не пройдя сначала основы разработки программного обеспечения.Я не собираюсь редактировать здесь, но вот несколько практических указателей, которые могут вам помочь:

  • используйте IDE, такую ​​как Eclipse.Не пишите код в командной строке с помощью блокнота.В этом случае Eclipse принесет вам огромную пользу только за простоту, с которой вы могли бы отлаживать свой код для устранения таких тривиальных ошибок.Вот что вы должны сделать: Загрузите Eclipse, создайте стандартный проект Java, скопируйте все ваши файлы .java и вставьте их в папку «src» проекта Eclipse.Затем добавьте несколько точек останова в строки, которые я упоминал выше, запустите и клиент, и сервер, попробуйте отправить файл и посмотреть, что происходит в вашем коде.

  • Выполните модульные тесты!Это очень важно, что бы ни говорили ваш профессор и коллеги.Выполнение модульных тестов будет иметь двойную выгоду для вашего кодирования: 1. Это поможет вам легко обнаружить такие регрессорные ошибки регрессии.2. это заставит вас писать хороший чистый код с индивидуальными методами для каждой задачи и т. Д.

  • Хотя знание потоков и сокетов сервера / клиента на низком уровне неплохо, лучшеЧтобы достичь того, что вы пытаетесь сделать в этом проекте, используйте Java Messenger Service.Это фреймворк, который делает именно то, что вы хотите, а именно отправлять и получать все виды вещей (примитивы, объекты и т. Д.) Синхронно или асинхронно, и все строительные леса уже созданы для вас, вам нужно только реализовать бизнес-логику.Посмотрите, это может вам сильно помочь.

0 голосов
/ 11 сентября 2011

Похоже, в ConnectareClient.java есть небольшая логическая ошибка. Я полагаю, что условие отправки «ГОТОВО» должно быть условием НЕ, иначе он никогда не отправит этот ответ клиенту и не продолжит запись в файл. Я уже попробовал это и увидел, что файл копируется с клиента на сервер.

Ниже приведено изменение кода, которое я сделал в ConnectareClient.java


//Citeste calea fisierului
String filename = inReader.readLine();

// this seems should be a NOT condition
if(!filename.equals("")){
    //Trimit status READY la client
    outReader.write("READY\n");
    outReader.flush();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...