2017-03-06 1 views
0

간단한 채팅을하고 있는데, 서버와 클라이언트가 연결되어있는 것보다 훨씬 간단합니다. 클라이언트 측에서 소켓 등을 생성하는 것을 관리하는 ConnectionManager 클래스가 있습니다. 여기 핵심 방법이 있습니다 :java - 서버가 클라이언트로부터 메시지를받지 못합니다 (reader.readLine() == null?)

public class ConnectionManager { 
    private Socket socket; 
    private BufferedReader reader; 
    private PrintWriter writer; 

    public ConnectionManager(String URL, int port){ 
     tryConnectToServer(URL, port); 
    } 

    public BufferedReader getReader() { 
     return reader; 
    } 

    public PrintWriter getWriter() { 
     return writer; 
    } 
    private void tryConnectToServer(String ip, int servSocket) { 
     try{ 
      socket = new Socket(ip, servSocket); 
      writer = new PrintWriter(socket.getOutputStream()); 
      reader = new BufferedReader(
        new InputStreamReader(
          socket.getInputStream())); 
     } 
     catch (IOException ex){ 
      System.out.println("Unable to connect to specified server. Code pink"); 
      ex.printStackTrace(); 
     } 
    } 

연결 관리자 개체는 ChatGUI의 일부입니다. ChatGUI의 필드 라이터와 리더 SendButtonListener로 수득 ChatGUI의 JTextField로 (msgInput)와 함께 라이터를 전달하기 위해 CM에서 설정된다

private void addSendButton() { 
    JButton sendButton = new JButton("Send"); 
    sendButton.addActionListener(new SendButtonActionListener(writer, msgInput)); 
    panel.add(sendButton); 
    panel.add(this.msgArea); 
} 

이어서, actionPerformed 메소드는 않는다 :

public class SendButtonActionListener implements ActionListener{ 
private PrintWriter writer; 
private JTextField msgInput; 

public SendButtonActionListener(PrintWriter pr, JTextField mi){ 
    writer = pr; 
    msgInput = mi; 
} 

public void actionPerformed(ActionEvent event){ 
    writer.println(msgInput.getText()); 
    System.out.println("Sending: " + msgInput.getText()); 
    flushMessageInputField(); 
} 

private void flushMessageInputField(){ 
    msgInput.setText(""); 
} 

}

다른 한편 서버 쪽에서 나는 이것을 가지고있다 :

try{ 
     this.servSocket = new ServerSocket(port); 
     System.out.println("Server socket established"); 
    } 
    catch (IOException ex){ 
     System.out.println("Unable to establish server socket. Code pink \n"); 
     ex.printStackTrace(); 
    } 

그리고 위의 후이 온다 :

public void waitForClients(){ 
    System.out.println("The gates has been opened..."); 
    while (true){ 
     try { 
      Socket client = servSocket.accept(); 
      processClient(client); 
     } 
     catch (IOException ex){ 
      ex.printStackTrace(); 
     } 
    } 
} 

private void processClient(Socket client){ 
    writers.add(getClientWriter(client)); 
    startUpdateFrom(client); 
    System.out.println("New client connected: " + client.getPort()); 
} 

private PrintWriter getClientWriter(Socket client){ 
    try{ 
     return new PrintWriter(client.getOutputStream()); 
    } 
    catch (Exception ex){ 
     ex.printStackTrace(); 
    } 
    return null; 
} 

그리고 마지막으로, 새로운 스레드가 해당 클라이언트에서 새 메시지를 듣고 시작합니다입니다

private void startUpdateFrom(Socket client){ 
    new Thread(
      new WaitAndSendToAllFrom(client)) 
       .start(); 
} 

:

public class WaitAndSendToAllFrom implements Runnable{ 
    BufferedReader reader; 

    public WaitAndSendToAllFrom(Socket clientSocket){ 
     try{ 
      reader = new BufferedReader(
        new InputStreamReader(
          clientSocket.getInputStream())); 
     } 
     catch (IOException ex){ 
      ex.printStackTrace(); 
     } 
    } 

    public void run(){ 
     try{ 
      String message; 
      System.out.println("Thread: waiting for messages to send..."); 
      while (true){ 
       message = reader.readLine(); 
       while (message != null){ 
        System.out.println("Server: Sending message: " + message); 
        sendToAll(message); 
       } 
      } 
     } 
     catch (IOException ex){ 
      ex.printStackTrace(); 
     } 
    } 

    private void sendToAll(String message){ 
     List<PrintWriter> writers = ServerClientConnector.getWriters(); 
     for (PrintWriter pr : writers){ 
      pr.println(message + "\n"); 
      pr.flush(); 
     } 
    } 
} 

사이클은 "스레드 : 메시지를 보내기를 기다리는 중 ..."이되지만 더 이상 필요하지는 않습니다. reader.readLine()은 널 (sysout으로 확인)을 리턴합니다. 나는 그것을 디버깅하려했지만, 그렇게 많은 프로그래밍에 익숙하지 않았다. 특히 두 개의 서로 다른 코드를 서로 디버깅하는 것이었다. 나는 이것을 3 일 동안보고 있었고, 나는 심각하게 여기에서 붙어있다.

+0

당신은뿐만 아니라 클라이언트에서 메시지를 전송하는 코드를 게시 할 수 있습니까? 그건 그렇고, while (message! = null)'while.loop 내에서 메시지가 바뀌지 않으므로, WaitAndSendToAllFrom-> run-> while에 무한 루프가 있습니다. 당신이 요청한 문제는 다음 일 수 있습니다). –

+0

글을 쓰지 않고 글을 편집했지만 그게 전부라고 생각합니다 :). 다른 버그/오류를 미리 미리 - 나는 코드가 릴 비트와 리팩토링으로 변경되어야한다는 것을 알고 있지만, 지금은 그 소켓/독자/작가에 집중하고 있습니다. :) –

답변

0
while (true){ 
    message = reader.readLine(); 
    while (message != null){ 
     System.out.println("Server: Sending message: " + message); 
     sendToAll(message); 
    } 
} 

이것은 의미가 없습니다. 한 줄을 읽은 다음 테스트를 계속합니다. 변경할 수없는 루프에서 null입니다.

이를 작성하는 적절한 방법은 다음과 같습니다

while ((message = reader.readLine()) != null){ 
    System.out.println("Server: Sending message: " + message); 
    sendToAll(message); 
} 
+0

적어도이 방법은 초기 행이 적어도 통과하는지 확인하기 위해 설정되었습니다. 전에는 게시 한 방식대로했지만 readLine() 결과를 메시지에 할당하는 데 문제가 있다고 생각했습니다. 나는 그것이 어리석은 소리가 난다는 것을 압니다. 그러나 나는 모든 것을 시도하고있었습니다. –

+0

Programmig는 모든 것을 시도하는 것으로 구성되어 있지 않으며, 아무것도하지 않습니다. 당신은 분석적이어야합니다. – EJP

관련 문제