使用Java进行简单聊天时的奇怪行为

我上个月开始学习
java,现在我正在尝试编写一个简单的聊天程序,但我遇到了一些奇怪的事情,我很好奇它背后的原因.

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
public static void main(String[] args) throws IOException {
    String text = "";
    ServerSocket ss = new ServerSocket(21025);
    while (true){

        System.out.println("Waiting...");
        Socket s1 = ss.accept();
        System.out.println("Connection accepted from "+s1.getInetAddress());
        PrintStream pout = new PrintStream(s1.getOutputStream());
        pout.println("Connected to the server");

        new Thread(new Ricevitore(s1)).start();
     }
  }
}

public class Ricevitore implements Runnable {
String text = "";
Socket skt;
public Ricevitore(Socket skt){
    this.skt = skt;
}
@Override
public void run() {
    while (!text.equalsIgnoreCase("end")) {
        try {
            InputStream in = skt.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            text = br.readLine();
            if (!text.equalsIgnoreCase("end"))
            System.out.println(text);
        }
        catch (IOException e){}
    }
  }
}

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

    //Create a socket
    try (Socket s = new Socket("127.0.0.1", 21025)) {
        String text="";
        while(!text.equalsIgnoreCase("end")) {

           //Allows messages from server
            InputStream in = s.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            if (br.ready()) {
                Scanner server = new Scanner(br);
                String testoServer = br.readLine();
                System.out.println(testoServer);
            }

            //Allows to send text to the server
            OutputStream out = s.getOutputStream();
            PrintStream pout = new PrintStream(out);

            Scanner tastiera = new Scanner(System.in);
            text = tastiera.nextLine();
            pout.println(text);

        }
    }
  }
}

这是目前完整的程序,我的问题是这样的:既然我想避免打印单词“end”来关闭程序,我插入了

 if (!text.equalsIgnoreCase("end"))

但之后服务器不会显示消息“连接到服务器”,除非我先通过客户端输入内容.
如果我注释掉if语句,则“Connection accepted”和“Connected to server”这两条消息都会在预期的同时打印出来.
我不知道我的问题是否清楚,而且我很有兴趣了解为什么会发生这样的事情.

如果还有其他任何你认为错误的事情,我会很高兴在这里谈论他们.

最佳答案 我只有一个疯狂的猜测,但看起来很可能.

在您的客户端中,如果br.ready()返回true,则从服务器读取消息.可能会发生此函数返回false,并且客户端将等待用户的输入.

从客户端向服务器发送消息后,客户端重复测试,现在从服务器获取消息.

我无法解释为什么在服务器代码中删除if(!text.equalsIgnoreCase(“end”))会导致问题消失.在您从客户端发送消息之前,该行甚至不会执行.

所以我认为这只是一个巧合.涉及两个过程,结果取决于代码在两个进程中执行的速度.

我多次运行你的例子,一旦我没有收到来自服务器的问候,即使上面的if就在它的位置.

您的代码的一般建议:您不需要在每次迭代时创建输入/输出流以及Scanner,您应该只执行一次.

要结束通信会话,只要您收到用户的结束,就可以在客户端关闭PrintStream.您的服务器将从br.readLine()获取null.此时,您关闭br并完成run().

点赞