2011-03-12 3 views
0

자바 동시성을 연습하고 학습을 위해 채팅 클라이언트/서버를 사용하고 있습니다.Java 콘솔/읽기 및 쓰기 동시 수행

현재 클라이언트 당 한 쌍의 터미널 창 (수신자와 발신자)이 필요합니다. 그래서 정말로 발신자 클라이언트 그룹과 수신자 클라이언트 그룹이 있습니다. 나는 쌍으로 생각합니다.

데이터를 입력하고 콘솔/터미널 데이터를 동시에받을 수있는 간단한 방법이 있습니까?

차이가 있다면 입력을 에코 할 필요가 없습니다. 서버의 출력뿐입니다. 또한 터미널은 bash이므로 간단한 터미널 솔루션이 있습니까?

+0

이 [예제] (http://stackoverflow.com/questions/3245805)가 apropos인지 확인할 수 있습니다. – trashgod

+0

나는 스윙 솔루션이 효과가 있다는 것을 알고 있지만, 지금은이 터미널 창에 상당히 부분적이다. 정말 그렇게 간단한 것 같아요. – Quaternion

답변

1

원칙적으로 동일한 터미널을 동시에 읽고 쓰는 문제는 없어야합니다. 입출력을 위해 다른 스레드를 사용하십시오. 입력이 그 사이에있을 때 출력이 조금 엉망으로 보일 수도 있습니다.

윈도우 터미널과 같은 종류의 터미널을 사용하려면 다른 시스템에서 다른 터미널에 대해 자세히 설명하고 JNI (또는 일부 JNI-wrapping 라이브러리)가 필요할 수 있습니다.

0

콘솔 (즉, 표준 입력 및 출력 스트림)은 시작시 Java 프로세스에 운영 체제에 의해 제공됩니다. 하나 이상의 콘솔을 제공 할 수있는 운영 체제가 없다는 것을 알고 있습니다.

따라서 클라이언트와 서버를 별도의 Java 프로세스로 시작하고 TCP를 통해 통신하도록 권장합니다. 목표에 따라 Telnet 또는 IRC와 같은 기존 통신 프로토콜을 구현할 수 있습니다.이 프로토콜을 사용하면 이러한 프로토콜에 기존 클라이언트 응용 프로그램을 사용할 수 있지만 이러한 프로토콜은 모든 기능을 제공하지만 사용자보다 더 많은 명령을 구현할 수 있습니다 아마도 필요하거나 자신의 간단한 프로토콜을 정의해야합니다.이 경우 클라이언트도 구현해야합니다. 후자에 대해 갈

한 가지 방법은 같은 것을 할 수 있습니다 :

public class Client { 
    public static void main(String[] args) throws Exception { 
     Socket s = new Socket(args[0], Integer.parseInt(args[1])); 
     new Repeater(System.in, s.getOutputStream()).start(); 
     new Repeater(s.getInputStream(), System.out).start(); 
    } 
} 


public class Server { 
    public static void main(String[] args) throws Exception { 
     ServerSocket ss = new ServerSocket(Integer.parseInt(args[0])); 
     for (;;) { 
      Socket s = ss.accept(); 
      // simply echo for now. You can do more interesting things here ... 
      new Repeater(s.getInputStream(), s.getOutputStream()).start(); 
     } 
    } 
} 



class Repeater extends Thread { 
    final InputStream in; 
    final OutputStream out; 

    public Repeater(InputStream in, OutputStream out) { 
     this.in = in; 
     this.out = out; 
    } 

    @Override public void run() { 
     try { 
      byte[] buf = new byte[4096]; 
      int r; 
      while ((r = in.read(buf)) != -1) { 
       out.write(buf, 0, r); 
       out.flush(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

을 당신은 할 수 있습니다 :

java Server 55555 

와 다른 콘솔

java Client localhost 55555 

모든 라인 당신의

해당 콘솔에 입력하면 서버에서 다시 사용자에게 에코됩니다.

프로젝트가 성공적으로 완료되었습니다.

+0

나는 이미 클라이언트와 작동중인 서버를 가지고있다. 호기심에 불과합니다. 나는 각 터미널에 대해 표준 입출력을 리디렉션하는 방법을 두려워하고 있습니다. 어쩌면 클라이언트를 시작하기 전에 표준 입력을 파이프로 리디렉션하여 클라이언트가 비동기 적으로 읽도록 할 수 있습니다. – Quaternion