2017-04-12 4 views
0

명령 프롬프트를 통해 실행되는 간단한 다중 스레드 채팅 서버를 구축하려고합니다. 클라이언트는 서버에 연결하고 서버는 여러 클라이언트를 보유하지만 한 클라이언트에서 다른 클라이언트로 메시지를 보내거나 로그인하는 다른 사용자의 클라이언트에게 알리는 경우에도 클라이언트 명령 프롬프트에는 아무 것도 표시되지 않습니다. 당신이 PrintWriter.println(), 데이터가 버퍼에 쓸 데이터를 보낼 때다중 스레드 서버 채팅 Java - 메시지가 없으나 연결 중입니다.

public class Server { 
private static ServerSocket servSock; 
private static Socket clientSock; 
private static ArrayList<ClientThread> clientList; 
private static int IDcount = 0; 


public static void main(String args[]){ 
     // Get command line arguments. 
     if (args.length != 3) { 
     System.out.println("Required arguments: server port, block duration, timeout"); 
     return; 
     } 
     int port = Integer.parseInt(args[0]); 
     int blockDur = Integer.parseInt(args[1]); 
     int timeout = Integer.parseInt(args[2]); 

     try{ 
     servSock = new ServerSocket(port); 
     clientList = new ArrayList<ClientThread>(); 
     } 
     catch(IOException ex){ 
      System.err.println(ex); 
     } 


     while (true) { 
     try { 
      clientSock = servSock.accept(); 
      ClientThread thread = new ClientThread(clientSock); 
      clientList.add(thread); 
      thread.start(); 
     } catch (IOException e) { 
      System.out.println(e); 
     } 
     } 
    } 

private synchronized static void broadcast(String msg){ 
    System.out.print(msg); 
    for(int i = 0; i < clientList.size(); i++){ 
     ClientThread client = clientList.get(i); 
     client.send(msg); 
    } 

} 

synchronized static void unlist(int id){ 
for(int i = 0; i < clientList.size(); i++){ 
    ClientThread thread = clientList.get(i); 
    if(thread.id == id){ 
     clientList.remove(i); 
     return; 
     } 
    } 
} 

static class ClientThread extends Thread { 
    Socket sock; 
    BufferedReader tIn; 
    PrintWriter tOut; 

    int id; 
    String username; 
    String msg; 

    ClientThread(Socket sock){ 
     id = IDcount++; 
     this.sock = sock; 
     try{ 
      tIn = new BufferedReader(new InputStreamReader(sock.getInputStream())); 
      tOut = new PrintWriter(sock.getOutputStream()); 
      username = tIn.readLine(); 
      broadcast(username + " logged in"); 
     } 
     catch(IOException ex){ 
      System.err.println(ex); 
     } 
    } 

    public void run(){ 
     boolean loggedIn = true; 
     while(loggedIn){ 
      try{ 
       msg = tIn.readLine(); 
      } 
      catch (IOException ex){ 
       System.err.println(ex); 
      } 
      String[] parts = msg.split("\\s",2); 
      String type = parts[0]; 

클라이언트 코드는

public class Client{ 
private static Socket clientSock; 
private static BufferedReader in; 
private static PrintWriter out; 
private static Scanner scan; 

public static void main(String[] args) throws IOException { 
     if (args.length != 2) { 
      System.out.println("Required arguments: server IP, server port"); 
      return; 
      } 
     String host = args[0]; 
     int port = Integer.parseInt(args[1]); 

     clientSock = new Socket(host, port); 
     in = new BufferedReader(new InputStreamReader(clientSock.getInputStream())); 
     out = new PrintWriter(clientSock.getOutputStream()); 
     scan = new Scanner(System.in); 

     new ListenFromServer().start(); 
     boolean online = true; 

     System.out.println("Enter your username:"); 
     String username = scan.nextLine(); 

     out.println(username); 

     while(online){ 
      System.out.println("> "); 
      String msg = scan.nextLine(); 
      String[] parts = msg.split("\\s"); 
      String type = parts[0]; 
      send(msg); 
      if(type.equalsIgnoreCase("logout")){ 
       online = false; 
      } 


     } 
     logoff(); 
} 

     static void send(String msg) throws IOException{ 
      out.println(msg); 
     } 

     private static void logoff() throws IOException{ 
       in.close(); 
       out.close(); 
       scan.close(); 
       clientSock.close(); 
     } 

    static class ListenFromServer extends Thread{ 
     public void run(){ 
      while(true){ 
       try{ 
        String msg = in.readLine(); 
        System.out.println(msg); 
       } 
       catch(IOException ex){ 
        System.err.println(ex); 
       } 
      } 
     } 
    } 

    } 
+0

코드를 실행 해 보았습니까? 또한 원하지 않는 오류를 잡기도합니다. –

답변

0

유사하다. println 다음에 PrintWriter.flush()으로 전화하여 즉시 서버와 데이터를 송수신해야합니다.

그리고 ClientThread 생성자에서 username = tIn.readLine();을 호출하면 생성자가 메인 스레드에서 호출되기 때문에 메인 스레드를 차단합니다. 따라서 연결된 사용자는 사용자 이름을 보내지 않지만 다른 클라이언트는 연결할 수 없습니다.