为什么我的连接器没有收到主持人的消息?

时间:2019-04-22 23:35:57

标签: java sockets

摘要

我正在用Java开发一个简单的点对点国际象棋游戏。主机成功连接,但连接器未收到其消息。我正在使用PrintWriterBufferedReader发送和接收消息。我怀疑PrintWriter的行为异常,但是我不确定。

以前的研究

我搜索了“客户端未接收服务器的消息”,但是每个人都没有将printlnPrintWriter一起使用的问题。我确实使用了println,所以没有一个适用于我。我也将输入和输出字段移出了方法,移到了类中,一个答案说这样做是可行的,但是并不能解决问题。

某些代码

收听代码

try (ServerSocket serverSocket = new ServerSocket(this.port)) {
    // We need to connect with another computer
    if (this.other == null || this.other.isClosed()) {
        System.out.println("Looking for connection on port " + serverSocket.getLocalPort());
        this.in = null;
        this.out = null;
        // Listen for connectors
        this.other = serverSocket.accept();
        // Someone tried to connect, handle connection
        System.out.println("Player connected");
        this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
        this.out = new PrintWriter(this.other.getOutputStream(), true);
        // Autoflush is enabled!                                 ^^^^
        // This does not get to the client
        this.sendMessage("connectHost");
    }
    // We are currently connected to another computer, no need to look for more
    else {
        String input = this.in.readLine();
        System.out.println("Received '" + input + "'");

        if (input != null) {
            // Handle input
        }
    }
} catch (IOException ioe) {
    ioe.printStackTrace();
}

发送代码

if (this.out != null) {
    // See, it is println, so I don't need to call out.flush()...
    this.out.println(message);
    System.out.println("Sent '" + message + "'");
}

连接命令代码

try {
    // The host picks up on this
    this.other = new Socket(ip, port);
    this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
    this.out = new PrintWriter(this.other.getOutputStream(), true);
    // Works
    this.sendMessage("test");
} catch (IOException ioe) {
    ioe.printStackTrace();
}

问题

它应该在连接器上打印出Received 'connectHost',但是不会发生。相反,它阻止in.readLine()被调用而in尚未接收到数据。如果我插入in.ready()支票,它将始终返回false

连接器控制台

Looking for connection on port 57479
connect localhost 57478 // Command to connect to host
Sent 'test' // Successfully goes to the host
// Now it blocks. This is intended, but it should be saying "Received 'connectHost'" beforehand.

主机控制台

Looking for connection on port 57478
Player connected
Sent 'connectHost'
Received 'test' // Host gets it
// This also blocks, waiting for more messages, but that is intended.

更新: 我只是尝试在连接后直接发送一条消息(请参阅更新的代码),然后主机得到它。连接器仍然无法从主机获得连接器。

1 个答案:

答案 0 :(得分:0)

很明显...

serverSocket.accept()被阻止,阻止了连接器读取输入。因此,in.readLine()并不是问题。我做到了,因此用户必须告诉程序监听连接。现在可以了。

新代码

收听代码

try (ServerSocket serverSocket = new ServerSocket(this.port)) {
    if (this.listening && (this.other == null || this.other.isClosed())) {
        System.out.println("Looking for connection on port " + serverSocket.getLocalPort());
        this.in = null;
        this.out = null;
        this.other = serverSocket.accept();
        this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
        this.out = new PrintWriter(this.other.getOutputStream(), true);
    } else if (this.in != null) {System.out.println("Looking for input");
        String input = this.in.readLine();
        System.out.println("Received '" + input + "'");

        if (input != null) {
            // Process input
        }
    }
} catch (IOException ioe) {
    ioe.printStackTrace();
}

发送代码不变。

连接代码

if (input.contains("connect")) {
    String[] args = input.replaceAll("connect ", "").split(" ");
    String ip = args[0];
    int port = Integer.parseInt(args[1]);

    try {
        this.other = new Socket(ip, port);
        this.in = new BufferedReader(new InputStreamReader(this.other.getInputStream()));
        this.out = new PrintWriter(this.other.getOutputStream(), true);
        this.sendMessage("connect");
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
} else if (input.contains("listen")) {
    this.listening = true;
}