【问题标题】:the ReadLine doesnt wait for inputReadLine 不等待输入
【发布时间】:2015-07-15 02:46:06
【问题描述】:

我有一个套接字客户端向套接字服务器发送文本,但 ReadLine 似乎没有等待接收行,然后继续。这是接收文本的服务器:

public void run() {

        try {

            serveurSocket = new ServerSocket(PORT_ID);  
            connexionSocket = serveurSocket.accept();


            BufferedReader reader = new BufferedReader(new InputStreamReader(connexionSocket.getInputStream()));
            PrintWriter writer = new PrintWriter(connexionSocket.getOutputStream(), true);

            messageRecu = "";
            while (true) {
                messageRecu = reader.readLine();
                messageRecu = messageRecu.toUpperCase();
                writer.println(messageRecu);
            }

            //reader.close();
            //writer.close();


        } catch (IOException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }

    }

在客户端和服务器之间建立套接字后,执行将在 reader.readLine 处停止,直到我通过套接字手动发送一个字符串。这是正常的和想要的。代码恢复并且它很好,直到它循环回到 reader.ReadLine() 那里它将读取一个“空”行而不是像第一次那样等待来自套接字的输入......这显然会弄乱下一个命令大写。那么我该如何解决呢?

编辑:如果可以帮助理解,我会添加客户端。

public class ClientSocket {

    private Socket clientSocket;

    public boolean isClosed() { return clientSocket.isClosed(); }

    public boolean connectToSocket (String ip, int port) {

        try {
            clientSocket = new Socket(ip, port);
            return true;
            } 
        catch (IOException e) { 
            System.out.println(e); 
            return false;
        }

    }

    public String sendToServer(String messageClient) {

        String messageRecu = "";

        try {

            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);

            writer.println(messageClient);
            messageRecu = reader.readLine();

            reader.close();
            writer.close();

            return messageRecu;

        } 
        catch (IOException e) {

            System.out.println(e.getMessage());
            e.printStackTrace();

            return messageRecu;

        }

    }

}

按下按钮将调用“connectTosocket”来启动套接字。按下第二个按钮将使用“sendToServer”发送文本字段的内容。

服务器确实接收到消息并将其返回大写,但我希望套接字与服务器保持打开状态,并且如果我发送另一个字符串以发生相同的序列。甚至不确定它是否可以完成:(

【问题讨论】:

  • null 返回时,流已终止。是时候关闭 BufferedReader,而不是继续阅读了。问题出在您的服务器代码中,您需要了解为什么它会在您不期望的情况下终止流。同时删除客户端中的while (true),因为这是危险代码。

标签: java sockets


【解决方案1】:

根据BufferedReader#readLine 的文档,如果到达流的末尾,则返回null。

将您的阅读循环更改为:

while ((messageRecu = reader.readLine()) != null) {
    messageRecu = messageRecu.toUpperCase();
    writer.println(messageRecu);
}
//Get out of the loop when the end of stream is reached.

按照 Java 教程的Reading from and Writing to a Socket 章节。

附带说明,while(true) 循环 are not really appreciated

【讨论】:

  • 最后,一个不错的答案。 1+
  • @Ouney:如果流仍处于打开状态,则不应发送 null。我们不知道他的服务器代码是什么样的,但它正在终止流,所以它可能做错了什么。解决方案是不要尝试在客户端中编程。
  • 这将不起作用,因为将发送的第一个 null 将关闭连接,并且不会接受新的请求。
  • @Ouney 服务器无法发送更多数据。它已关闭连接。
  • @alfasin 不可能 发送空值,并且此代码中没有任何内容阻止接受新连接。
【解决方案2】:

来自客户端的连接结束的“null”信号 - 这就是连接断开的原因。如果要支持多个请求,则应每次运行一个新的ServerSocket.accept() 并等待新的客户端连接。

KKMultiServer class:

import java.net.*;
import java.io.*;


public class KKMultiServer {
    public static void main(String[] args) throws IOException {

    if (args.length != 1) {
        System.err.println("Usage: java KKMultiServer <port number>");
        System.exit(1);
    }

        int portNumber = Integer.parseInt(args[0]);
        boolean listening = true;

        try (ServerSocket serverSocket = new ServerSocket(portNumber)) { 
            while (listening) {
                new KKMultiServerThread(serverSocket.accept()).start();
            }
        } catch (IOException e) {
            System.err.println("Could not listen on port " + portNumber);
            System.exit(-1);
        }
    }
}

KKMultiServerThread class:

import java.net.*;
import java.io.*;

public class KKMultiServerThread extends Thread {
    private Socket socket = null;

    public KKMultiServerThread(Socket socket) {
        super("KKMultiServerThread");
        this.socket = socket;
    }

    public void run() {

        try (
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(
                    socket.getInputStream()));
        ) {
            String inputLine, outputLine;
            KnockKnockProtocol kkp = new KnockKnockProtocol();
            outputLine = kkp.processInput(null);
            out.println(outputLine);

            while ((inputLine = in.readLine()) != null) {
                outputLine = kkp.processInput(inputLine);
                out.println(outputLine);
                if (outputLine.equals("Bye"))
                    break;
            }
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

您可以在Oracle tutorials阅读更多关于套接字的信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2017-04-17
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多