2015-01-26 6 views
1

Я пишу клиентское приложение Java (базовый пакет Java Net с TCP/IP). Клиент должен принимать входные данные из system.in и в то же время должен слушать любые сообщения, поступающие с сервера через вход сокетов. После того, как будет получен вход из системы system.in, клиент получит этот ввод, выполнит некоторую обработку и отправит его на сервер в качестве запроса. Поэтому в основном 2 процессы выполняются,Многопоточный Java-клиент TCP

-Прослушивание по запросу клиента

-listning для ответов сервера.

Я реализовал 2 потока для этого и управлял обработкой сообщений в основной теме. Это достаточно хороший дизайн.?

И есть способ вернуть сообщение, полученное от system.in в основной поток. Метод thread run() возвращает void. Я использовал переменную volatile, чтобы вернуть полученную строку, но ее сказали, что volatile очень дорогостоящий, поскольку он не использует кеш процессора для хранения переменной.

+0

Почему? Вам нужно только получить ответ после отправки запроса. Для этого вам не нужны два потока. – EJP

+0

Его необходимо, чтобы сервер отправлял некоторые определения при подключении, поэтому клиент должен его слушать, и он также должен прослушивать запросы от system.in в одно и то же время. – ndnine89

ответ

0

Вы можете просмотреть эти два проекта, которые я написал для примера сокетов Java и многопоточности.

Я предполагаю, что ClientExample это один вы searcing для но вы посмотрите на серверной части может тоже.

В принципе идея состоит в том, чтобы запустить два отдельных потока, которые прослушивают разные входы - разъем и консоль.

final Thread outThread = new Thread() { 
    @Override 
    public void run() { 
     System.out.println("Started..."); 
     PrintWriter out = null; 
     Scanner sysIn = new Scanner(System.in); 
     try { 
      out = new PrintWriter(socket.getOutputStream()); 
      out.println(name); 
      out.flush(); 

      while (sysIn.hasNext() && !isFinished.get()) { 
       String line = sysIn.nextLine(); 
       if ("exit".equals(line)) { 
        synchronized (isFinished) { 
         isFinished.set(true); 
        } 
       } 
       out.println(line); 
       out.flush(); 
       disconnect(); 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 
      if (out != null) { 
       out.close(); 
      } 
     } 
    }; 
}; 
outThread.start(); 

и другой поток для ввода сокета:

 final Thread inThread = new Thread() { 
      @Override 
      public void run() { 
       // Use a Scanner to read from the remote server 

       Scanner in = null; 
       try { 
        in = new Scanner(socket.getInputStream()); 
        String line = in.nextLine(); 
        while (!isFinished.get()) { 
         System.out.println(line); 
         line = in.nextLine(); 
        } 
       } catch (Exception e) { 
//     e.printStackTrace(); 
       } finally { 
        if (in != null) { 
         in.close(); 
        } 
       } 
      }; 
     }; 
     inThread.start(); 

Я надеюсь, что это поможет :)

+0

Это было очень полезно! Но я должен передать консольный ввод в основной поток, прежде чем записывать его в сокет. Есть ли способ вернуть sysIn в основной поток? – ndnine89

+0

Нужно ли обрабатывать входные данные в основном потоке? Не можете ли вы вызвать метод обработки в фоновом потоке? –

+0

Благодарим вас за предложение, но если обработка потока требует времени. Неправильно использовать несколько потоков? Поток будет заблокирован при обработке system.in. – ndnine89

Смежные вопросы