2014-10-20 2 views
0

여기 내 질문은 클라이언트간에 msg를 교환하는 방법입니까? 어떻게 클라이언트가 "BYE"또는 "QUIT"를 보낼 때까지 텍스트 메시지를위한 방법을 개발할 수 있습니까? 이 서버간단한 클라이언트/서버 응용 프로그램 교환 msg

public SocketServer(int port) { 
    this.port = port; 
} 

public void start() throws IOException { 
    System.out.println("Starting the socket server at port:" + port); 
    serverSocket = new ServerSocket(port); 

    //Listen for clients. Block till one connects 

    System.out.println("Waiting for clients..."); 
    Socket client = serverSocket.accept(); 

    //A client has connected to this server. Send welcome message 
    sendWelcomeMessage(client); 
} 

private void sendWelcomeMessage(Socket client) throws IOException { 
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); 
    writer.write("Hello. You are connected to a Simple Socket Server. What is your name?"); 
    writer.flush();  
    writer.close(); 
} 

의 코드와이 클라이언트에 대한

public SocketClient(String hostname, int port){ 
    this.hostname = hostname; 
    this.port = port; 
} 

public void connect() throws UnknownHostException, IOException{ 
    System.out.println("Attempting to connect to "+hostname+":"+port); 
    socketClient = new Socket(hostname,port); 
    System.out.println("Connection Established"); 
} 

public void readResponse() throws IOException{ 
    String userInput; 
    BufferedReader stdIn = new BufferedReader(new InputStreamReader(socketClient.getInputStream())); 

    System.out.println("Response from server:"); 
    while ((userInput = stdIn.readLine()) != null) { 
     System.out.println(userInput); 
    } 
} 
+0

이 보인다 "BYE"또는 "종료"루프를 종료 – Leo

답변

0

새로운 ServerSocket의입니다 (호스트 이름, 포트)는 '포트'에 바인딩 만 받아 들일 수있는 새로운 소켓을 생성 새로운 연결. 데이터 통신에는 사용되지 않습니다.

새 클라이언트가 서버에 연결되면 ServerSocket.accept()는 완전히 새로운 소켓 객체를 반환하고 클라이언트 (Reader/Writer를 통해 가능)와의 통신에 사용됩니다.

현재 ServerSocket은 여전히 ​​완벽하게 유효하며 accept()를 다시 호출하면 새 클라이언트 소켓 객체의 수명주기와 완전히 독립적입니다.

ServerSocket.accept()를 다시 호출하면 다음 클라이언트를 기다린 후 다음 차례로 기다립니다.

accept()에서 반환 된 클라이언트 연결을 "닫기()"한 시점에서 확인하십시오.

중요한 개념은 "통화 차단"입니다. accept()는 새 클라이언트가 연결될 때까지 다음 코드 행을 실행할 수 없습니다. readLine()은 상대방에 의해 일부 데이터가 전송 될 때까지 다음 코드 행을 실행할 수 없습니다.

여러 클라이언트를 동시에 제공하려면 스레드 풀을 만들고 다음 사용 가능한 스레드를 사용하여 새 클라이언트에 대한 프로토콜 처리기를 실행하십시오. 그런 다음 "블로킹"읽기/쓰기 작업은 스레드의 주 코드에서 격리되며 주 코드는 "accept()"를 다시 호출 할 수 있습니다.

예. 서버 코드에 대한 간단한 확장은 여러 클라이언트 요청을 처리 할 수 ​​있도록 다음과 같습니다

System.out.println("Waiting for clients..."); 
while(!done) { 
    final Socket client = serverSocket.accept(); 

    new Thread() { 
    public void run() { 
     try { 
      sendWelcomeMessage(client); 
     } finally { 
      client.close(); 
     } 
    }.start(); 
} 

sendWelcomeMessage: 
    send welcome 
    read input 
    if input=="bye" then done=true 
코드가 오라클 사이트에서 찾을 수 있습니다 거의 동일

기본 설명과 예 ​​: http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later

또한해야 멀티 스레딩에 대한 좋은 자습서를 읽으십시오. 이것을 시도해보십시오. http://docs.oracle.com/javase/tutorial/essential/concurrency/

+0

미안하지만, 메신저는 어떻게 2 개의 클라이언트가 서로에게 메시지를 보낼지 물어 보았습니다. 그들 중 ne는 Bye 또는 Quit –

0

몇 달 전,이 코드 (APP Chat java)를 Netbeans (저에게 적합합니다)라고 적어두면 도움이됩니다.

서버 부분

/** 
* Server 
* @author Zied 
*/ 
public class ChatServer implements Runnable ,ActionListener{ 

    private JFrame jfrm; 
    private ServerSocket serverSocket; 
    private Socket socketClient; 
    private ObjectInputStream ois; 
    private ObjectOutputStream oos; 
    private JTextArea jta; 
    private JScrollPane jscrlp; 
    private JTextField jtfInput; 
    private JButton jbntSend; 

    public ChatServer() { 

     jfrm=new JFrame("Chat Server"); 
     jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jfrm.setLayout(new FlowLayout()); 
     jfrm.setSize(300,320); 
     Thread myThread =new Thread(this); 
     myThread.start(); 
     jta= new JTextArea(15, 15); 
     jta.setEditable(false); 
     jta.setLineWrap(true); 
     jscrlp=new JScrollPane(jta); 
     jtfInput=new JTextField(15); 
     jtfInput.addActionListener(this); 
     jbntSend=new JButton("Send"); 
     jbntSend.addActionListener(this); 
     jfrm.getContentPane().add(jscrlp); 
     jfrm.getContentPane().add(jbntSend); 
     jfrm.getContentPane().add(jtfInput); 
     jfrm.setVisible(true); 


    } 

    /***** main ******/ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ChatServer(); 
      } 
     }); 

    } 

    public void actionPerformed(ActionEvent ae) 
    { 

     if (ae.getActionCommand().equals("Send")|| ae.getSource() instanceof JTextField) 
     { 
      try { 
       oos.writeObject(jtfInput.getText()); 
       jta.setText(jta.getText()+"You say :"+jtfInput.getText()+"\n"); 
       jtfInput.setText(""); 
      } catch (IOException e) { 
      } 
     } 
    } 

    public void run() { 
     try 
     { 
      serverSocket = new ServerSocket(4444); 
      socketClient =serverSocket.accept(); 
      String s= String.valueOf(serverSocket.getLocalPort()); 
      oos=new ObjectOutputStream(socketClient.getOutputStream()); 
      ois=new ObjectInputStream(socketClient.getInputStream()); 
      while(true) 
      { 
       Object input=ois.readObject(); 
       jta.setText(jta.getText()+"Client says :"+ (String)input +"\n"); 

       if (input.equals("bye")) 
       { 
        System.exit(0); 
       } 
      } 


     }catch(IOException e) 
     { 
      e.printStackTrace(); 
     }catch (ClassNotFoundException e) 
     { 
      e.printStackTrace(); 

     } 
    } 
} 

클라이언트 부분 :

/** 
* Client 
* @author Zied 
*/ 
public class ChatClient implements Runnable ,ActionListener{ 

    private JFrame jfrm; 
    private Socket socket; 
    private ObjectInputStream ois; 
    private ObjectOutputStream oos; 
    private JTextArea jta; 
    private JScrollPane jscrlp; 
    private JTextField jtfInput; 
    private JButton jbntSend; 

    public ChatClient() { 

     jfrm=new JFrame("Chat Client"); 
     jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jfrm.setLayout(new FlowLayout()); 
     jfrm.setSize(300,320); 
     Thread myThread =new Thread(this); 
     myThread.start(); 
     jta= new JTextArea(15, 15); 
     jta.setEditable(false); 
     jta.setLineWrap(true); 
     jscrlp=new JScrollPane(jta); 
     jtfInput=new JTextField(15); 
     jtfInput.addActionListener(this); 
     jbntSend=new JButton("Send"); 
     jbntSend.addActionListener(this); 
     jfrm.getContentPane().add(jscrlp); 
     jfrm.getContentPane().add(jbntSend); 
     jfrm.getContentPane().add(jtfInput); 
     jfrm.setVisible(true); 

    } 


    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 

      SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ChatClient(); 
      } 
     }); 
    } 

    @Override 
    public void run() { 
    try 
     { 
      socket=new Socket("localhost",4444); 
      oos=new ObjectOutputStream(socket.getOutputStream()); 
      ois=new ObjectInputStream(socket.getInputStream()); 

      while(true) 
      { 
       Object input=ois.readObject(); 
       jta.setText(jta.getText()+"Server says :"+ (String)input +"\n"); 
       if (input.equals("bye")) 
       { 
        System.exit(0); 
       } 
      } 


     }catch(IOException e) 
     { 
      e.printStackTrace(); 
     }catch (ClassNotFoundException e) 
     { 
      e.printStackTrace(); 

     } } 

    @Override 
    public void actionPerformed(ActionEvent ae) { 

     if (ae.getActionCommand().equals("Send")|| ae.getSource() instanceof JTextField) 
     { 
      try { 
       oos.writeObject(jtfInput.getText()); 
       jta.setText(jta.getText()+"You say:"+jtfInput.getText()+"\n"); 
       jtfInput.setText(""); 
      } catch (IOException e) { 
      } 
     } 
    } 

} 보낼 곳 사용자를 기다리는 동안 루프를 필요로 같은

+0

을 보낼 수 있습니까? 다른 PC에서 둘 이상의 클라이언트를 사용할 수 있습니까? –

관련 문제