【问题标题】:Cannot invoke "java.net.ServerSocket.close()" because "Server.server" is null无法调用“java.net.ServerSocket.close()”,因为“Server.server”为空
【发布时间】:2022-01-10 13:11:39
【问题描述】:

我正在尝试编写一个简单的客户端/服务器应用程序。我在客户端有一个数据,它变成一个整数数组并传输到服务器。服务器进行计算并将它们返回给客户端。但我的程序属于这个例外。

对不起,长文,我只是在学习,真的需要你的帮助。

public class Client {

    private static Socket clientSocket;
    private static ObjectInputStream in;
    private static ObjectOutputStream out;
    private static int[] parsedValue;

    public Client(String input) {
        try {
            parsedValue = Arrays.stream(input.split(",")).mapToInt(Integer::parseInt).toArray();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Client(int[] input) {
        parsedValue = input;
    }

    public Client(List<Integer> input) {
        try {
            parsedValue = input.stream().mapToInt(d->d).toArray();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static void main(String[] args) {
        try {
            try {

               clientSocket = new Socket("localhost", 4004);
               in = new ObjectInputStream(clientSocket.getInputStream());
               out = new ObjectOutputStream(clientSocket.getOutputStream());


                String clientTestString = "440,5,16";
                Client stringClient = new Client(clientTestString);
                out.writeObject(stringClient.parsedValue);
                out.flush();
                System.out.println(in.readObject());


                int[] clientIntsTest = {39, 10, 5};
                Client arrayClient = new Client(clientIntsTest);
                out.writeObject(arrayClient.parsedValue);
                out.flush();
                System.out.println(in.readObject());


                List<Integer> clientsTestList = Arrays.asList(781, 9, 7);
                Client listClient = new Client(clientsTestList);
                out.writeObject(listClient.parsedValue);
                out.flush();
                System.out.println(in.readObject());


            } finally {
                System.out.println("Client was closed");
                clientSocket.close();
                in.close();
                out.close();
            }
        } catch (IOException | ClassNotFoundException e) {
            System.err.println(e);
        }

    }
}
public class Server {

    private static Socket clientSocket;
    private static ServerSocket server;
    private static ObjectInputStream in;
    private static ObjectOutputStream out;
    private static int[] parsedValue;


    public String getResult() {
        return calculation(parsedValue);
    }


    public String calculation(int[] parsedValue) {
        parsedValue[0] = toDecimal(parsedValue[0], parsedValue[1]);

        String answer = "";
        int temp = 0;
        String digits = new String("ABCDEF");

        while (parsedValue[0] > 0) {
            temp = parsedValue[0] % parsedValue[2];

            if (temp < 10) {
                answer = temp + answer;
            } else {
                answer = digits.charAt(temp - 10) + answer;
            }
            parsedValue[0] /= parsedValue[2];
        }

        return answer;
    }

    public int toDecimal(int value, int baseNotation) {
        int i = 0;
        int decimalNumber = 0;
        if (value > 0) {
            while (value != 0) {
                decimalNumber += (value % 10) * Math.pow(baseNotation, i);
                value /= 10;
                i++;
            }
        }
        return decimalNumber;
    }


    public static void main(String[] args) {
        try {
            try {
                server = new ServerSocket(4004);
                System.out.println("Server runs");

                clientSocket = server.accept();

                try {

                    in = new ObjectInputStream(clientSocket.getInputStream());
                    out = new ObjectOutputStream(clientSocket.getOutputStream());

                    parsedValue = (int[]) in.readObject();
                    System.out.println(parsedValue);
                    Server examp = new Server();
                    String answer = examp.getResult();
                    System.out.println(answer);
                    out.writeObject(answer);
                    out.flush();


                } finally {
                    clientSocket.close();
                    in.close();
                    out.close();
                }
            } finally {
                System.out.println("Server closed");
                server.close();
            }
        } catch (IOException | ClassNotFoundException e) {
            System.err.println(e);
        }
    }
}

【问题讨论】:

    标签: java client-server


    【解决方案1】:

    这两行

       Server examp = new Server();
       String answer = examp.getResult();
    

    您创建了一个覆盖字段private static ServerSocket server;的新对象

    更好的解决方案是将 main() 中的逻辑放入一个单独的方法中,如 run(),在 main() 中实例化一个新的服务器对象并在其上调用 run()。不要忘记通过删除 static 关键字将所有字段设为实例成员。

    public static void main(String[] args) {
        Server examp = new Server();
        examp.run();
    }
    
    public void run() {
        try {
            try {
            server = new ServerSocket(4004);
            System.out.println("Server runs");
    
            clientSocket = server.accept();
    
            try {
    
                in = new ObjectInputStream(clientSocket.getInputStream());
                out = new ObjectOutputStream(clientSocket.getOutputStream());
    
                parsedValue = (int[]) in.readObject();
                System.out.println(parsedValue);
                String answer = getResult();
                System.out.println(answer);
                out.writeObject(answer);
                out.flush();
    
    
            } finally {
                clientSocket.close();
                in.close();
                out.close();
            }
            } finally {
                System.out.println("Server closed");
                server.close();
            }
            } catch (IOException | ClassNotFoundException e) {
                System.err.println(e);
        }
    }
    

    顺便说一句:您应该始终使用这种模式来摆脱“静态陷阱”。所以我建议你也重构你的 Client 类。

    【讨论】:

    • 我的问题已经解决了,非常感谢!!!
    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-18
    • 2022-11-19
    • 1970-01-01
    • 2021-12-20
    • 2021-07-20
    相关资源
    最近更新 更多