2016-08-15 2 views
0

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

Я уже писал классы сервера, клиента и ThreadedConnection. Моя цель на данный момент заключается в том, что сообщение от одного из клиентов будет показано другим клиентам. Мой текущий код работает следующим образом: когда один клиент отправляет сообщение, другие получают его только при отправке своего собственного сообщения. пример: Client1: привет
привет
Client2 привет
привет
Client3 Что до
привета

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

if((message=stdin.readLine())!=null) 
      out.println(message); 
if((message=in.readLine())!=null) 
      System.out.println(message); 

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

Серверный код:

import java.io.*; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 

public class Server { 

    private static List<ThreadedConnection> clientList=new ArrayList<>();; 

    public synchronized void broadcastMessageToAllClients(String message){ 

     for(ThreadedConnection tc: clientList) 
      tc.sendMessage(message); 
    } 

    public static void main(String[] args) throws IOException { 

     try { 

      Server server=new Server(); 
      ServerSocket serverSocket = new ServerSocket(8189); 

      while (true) { 

       Socket socket = serverSocket.accept(); 
       Runnable threadedServer = new ThreadedConnection(socket, server); 
       clientList.add((ThreadedConnection)threadedServer); 
       Thread thread = new Thread(threadedServer); 
       thread.start(); 
      } 
     } catch (Exception e) { 

      System.out.println("An error occured."); 
      e.printStackTrace(); 
     } 
    } 
} 

код ThreadedConnection:

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

public class ThreadedConnection implements Runnable { 

    private Server server; 
    private Socket socket; 
    private PrintWriter out; 
    private BufferedReader in; 

    public ThreadedConnection(Socket socket, Server server) { 

     this.socket = socket; 
     this.server = server; 
    } 

    @Override 
    public void run() { 

     try { 

      out = new PrintWriter(socket.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

      String message; 
      while(true){ 

       if((message=in.readLine())!=null) 
        server.broadcastMessageToAllClients(message); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendMessage(String message){ 

     out.println(message); 
    } 
} 

код клиента:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

public class Client { 

    public static void main(String[] args) throws IOException { 

     try (
       Socket socket = new Socket("127.0.0.1", 8189); 
       PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
       BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 
     ) { 

      String message; 
      while(true){ 

       if((message=stdin.readLine())!=null) 
        out.println(message); 
       if((message=in.readLine())!=null) 
        System.out.println(message); 
      } 
     } 
    } 
} 
+0

У вас должен быть поток, предназначенный для чтения с разъема. Кроме того, вы можете посмотреть ServerSocketEx (https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/), который является основой для обработки сокетов – ControlAltDel

+0

, спасибо, я постараюсь работать над Это. – drapo

ответ

0

Если вы хотите получать сообщения из консоли и из гнезда в то В то же время вы должны разделить эти функции на два потока. Таким образом, консольный ридер будет оставаться в основном потоке (как в вашем фактическом коде), но считыватель сокетов должен быть в новом потоке.

Это происходит потому, что функция readLine() BufferedReader ждет, пока не будет получен следующий вход. Это означает, что ваш сокет-ридер вызывается только при вводе некоторого текста в консоли.

+0

спасибо за ваш ответ, он работает очень хорошо :) – drapo

+0

Добро пожаловать;) (Отметьте мой ответ как решение: p) – Creart

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