You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Socket客户端向服务器传输账号密码并验证返回布尔值故障排查

问题:客户端登录信息无法传输到服务器,服务器未获取到用户名和密码

核心原因

客户端代码中,Socket、DataInputStream、DataOutputStream是在main方法的局部作用域内创建的,loginMessage()方法根本无法访问这些对象。加上所有catch块都直接吞掉异常,导致空指针错误被隐藏,数据完全没有发送到服务器,服务器则一直阻塞在readUTF()步骤,表现为未获取到值。

修复步骤

1. 将Socket、数据流改为类成员变量

在客户端类(比如MyApplication)顶部添加成员变量,让loginMessage()能访问到通信对象:

// MyApplication类的成员变量声明
private Socket socket;
private DataInputStream din;
private DataOutputStream dout;

2. 在main方法中初始化成员变量

把原来main方法里的局部变量赋值给成员变量,而非创建局部变量:

public static void main(String[] args) {
    MyApplication x = new MyApplication(); // 先创建实例,再初始化通信对象
    try {
        x.socket = new Socket("127.0.0.1", 7000);
        x.din = new DataInputStream(x.socket.getInputStream());
        x.dout = new DataOutputStream(x.socket.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace(); // 打印异常,方便调试
    }

    // 后续线程启动逻辑保持不变
    Progress a = new Progress();
    Secondpage s = new Secondpage();
    Thread t1 = new Thread(x);
    t1.start();
    try {
        t1.join();
    } catch (Exception e) {
        e.printStackTrace();
    }
    a.start();
    try {
        a.join();
    } catch (Exception e) {
        e.printStackTrace();
    }
    s.start();
    try {
        s.join();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

3. 修改loginMessage()的异常处理与数据发送

去掉空catch块,打印异常信息,同时调用flush()确保数据立即发送:

private void loginMessage() {
    String uName = txtUsername.getText();
    try {
        dout.writeUTF(uName);
        dout.flush(); // 强制发送缓冲区数据
    } catch (Exception e) {
        e.printStackTrace();
    }
    String password = new String(usPassword.getPassword());
    try {
        dout.writeUTF(password);
        dout.flush();
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        boolean loginSuccess = din.readBoolean();
        if (loginSuccess) {
            JOptionPane.showMessageDialog(this,
                    "Thank you for logging in " + uName
                            + ". You will now get redirected to our Customer Zone, where you can make purchases. Press OK to continue.",
                    "Success!", JOptionPane.INFORMATION_MESSAGE);
            finished = true;
        } else {
            JOptionPane.showMessageDialog(this,
                    "Error. Either your username or password is incorrect. Please try again.", "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

4. 服务器端优化(可选)

为避免服务器无限等待客户端数据,给Socket设置超时:

public static void main(String[] args) {
    try {
        ServerSocket serverSocket = new ServerSocket(7000);
        System.out.println("Waiting for a client...");
        Socket mySocket = serverSocket.accept();
        mySocket.setSoTimeout(10000); // 设置10秒超时
        System.out.println("I have a client");
        DataInputStream clientIn = new DataInputStream(mySocket.getInputStream());
        DataOutputStream clientOut = new DataOutputStream(mySocket.getOutputStream());
        uname = clientIn.readUTF();
        pwd = clientIn.readUTF();
        System.out.println("Received username: " + uname + ", password: " + pwd);
        boolean verif = verifyUserLogin(uname, pwd, filepath, sep);
        clientOut.writeBoolean(verif);
        clientOut.flush();
        System.out.println("Verification result sent: " + verif);

    } catch (Exception e) {
        e.printStackTrace(); // 打印完整异常栈
    }
}

额外注意事项

  • 禁止使用空catch块吞掉异常,至少打印异常信息,否则调试会非常困难
  • 写入数据流后调用flush(),避免数据滞留在缓冲区
  • 服务器verifyUserLogin方法中,需处理文件不存在、行格式错误的情况,防止数组越界

内容的提问来源于stack exchange,提问作者whiffed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:20:20