【问题标题】:java - server not recieving messages from client (reader.readLine() == null ?)java - 服务器未从客户端接收消息(reader.readLine() == null ?)
【发布时间】:2017-03-06 06:06:44
【问题描述】:

所以我一直在进行简单的聊天,而不是有一个服务器和一堆连接到它们的客户端。在客户端,我有类 ConnectionManager 来管理创建套接字等。这是它的核心方法:

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 的字段 writer 和 reader 是从 CM 获取和设置的,以便将 writer 与 ChatGUI 的 JTextField (msgInput) 一起传递给 SendButtonListener:

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() 返回 null(使用 sysout :) 检查)。我试图调试它,但我在编程方面没有那么丰富的经验,尤其是调试两个相互协作的独立代码。我已经看了 3 天了,我严重卡在这里。

【问题讨论】:

  • 你能发布从客户端发送消息的代码吗?顺便说一句,您在WaitAndSendToAllFrom-&gt;run-&gt;while(message != null) 中有一个无限循环 - while.loop 中的消息不可能更改,因此它将永远循环和循环(即使这不是您要求的问题,也可能是下一个一)。
  • 我已经编辑了这篇文章,写的不多,但我相信这就是所需要的:)。提前解决其他错误/错误 - 我知道代码需要稍微更改和重构,但现在我专注于那些该死的套接字/读取器/写入器:)。

标签: java sockets connection


【解决方案1】:
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);
}

【讨论】:

  • 我知道,这样设置只是为了检查初始行是否至少通过。以前,我已经按照您发布的方式进行了处理,但认为问题可能在于将 readLine() 结果分配给消息。我知道这听起来很愚蠢,但我正在尝试一切:)
  • Programmig 不包括尝试一切,也没有其他任何事情。你必须善于分析。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
相关资源
最近更新 更多