bufferedreader(socket.getinputstream)的readline()方法不等待来自客户端的输入

时间:2016-12-02 11:25:31

标签: java multithreading sockets bufferedreader

我正在使用java开发电子投票系统。客户端发送一个代表所请求方法的数字。然后,服务器线程的run()方法根据发送的号码等待来自套接字的输入。服务器正常读取第一个客户端请求的输入,但是我从服务器获得以下异常:

  

线程“Thread-0”中的异常java.lang.NumberFormatException:For   输入字符串:“test”at   java.lang.NumberFormatException.forInputString(未知来源)at   java.lang.Integer.parseInt(未知来源)at   java.lang.Integer.parseInt(未知来源)at   ServerThread.run(ServerThread.java:139)

然后线程异常终止(我得出结论,因为当我尝试从同一客户端GUI执行另一个操作时,我得到一个SocketException:Socket被关闭)。 user = Integer.parseInt(in.readLine());应该等待客户端发送另一个整数,但不是。它读取最后发送的字符串。 (我正在使用BufferedReader)

这是serverthread的运行方法:

public void run() {
    while (true) {
        int user = -1;
        // while ((user = Integer.parseInt(in.readLine())) != -1) {

        try {
            user = Integer.parseInt(in.readLine());
        } catch (IOException e) {
            System.out.println("Command Error");
        }

        switch (user) {
        case 1:
            try {
                String username = in.readLine();
                String password = in.readLine();
                int cid = -1;
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery(
                        "SELECT UUID FROM user_acc WHERE UUID IN (SELECT CID FROM candidate) AND username = '"
                                + username + "';");

                if (Security.Authenticate(username, password) && !username.equals("") && !password.equals(""))
                    out.println("true");
                else {
                    out.println("false");
                //  in.reset();
                    break;
                }
                if (rs.next()) {
                    cid = rs.getInt(1);

                    String inetAddress = clientSocket.getInetAddress().toString().substring(1);
                    stmt.executeUpdate(
                            "UPDATE candidate SET ipadd = '" + inetAddress + "' WHERE CID = " + cid + ";");
                }

            } catch (IOException e) {
                System.out.println("Writing in Sign in Error");
            } catch (UserNotExistingException e) {

            } catch (SQLException e) {
                e.printStackTrace();
            }
            break;

        case 2:
            try {
                String username = in.readLine();
                String name = in.readLine();
                String password = in.readLine();
                String email = in.readLine();
                String conf = in.readLine();
                if (Security.signUp(username, name, email, password, conf))
                    out.println("true");
                else
                    out.println("false");
            } catch (IOException e) {
                System.out.println("Reading in Sign Up Error");
            } catch (UsernameEmailExistsException e) {
                System.out.println("Email Exists");
                out.println("false");
            }
            break;

        case 3:
            try {
                String email = in.readLine();
                String code;
                if (Security.forgotPass(email)) {
                    out.println("true");
                    code = in.readLine();
                } else {
                    out.println("false");
                    break;
                }

                if (Security.checkCode(code, email))
                    out.println("true");
                else {
                    out.println("false");
                    break;
                }
                String newpass = in.readLine();
                String conf = in.readLine();
                String username = "";
                for (int i = 0; i < email.length(); i++)
                    if (email.charAt(i) == '@')
                        break;
                    else
                        username += email.charAt(i);

                if (Security.forceChangePassword(username, newpass, conf)) {
                    out.println("true");
                } else
                    out.println("false");
            } catch (IOException e) {
                System.out.println("Reading in Forget Pass Error");
            }
            break;

        case 4:
            try {
                int CID = Integer.parseInt(in.readLine()), userID = Integer.parseInt(in.readLine());
                try {
                    if (nominate(CID, userID))
                        out.println("true");
                    else
                        out.println("false");
                } catch (ClassNotFoundException | SQLException | UserNotExistingException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;

        case 5:
            try {
                int uid = Integer.parseInt(in.readLine());
                String candname = in.readLine();
                if (vote(candname, uid))
                    out.println("true");
                else
                    out.println("false");
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;

        case 6:

            break;

        case 7:
            try {
                String text = in.readLine();
                int UID = Integer.parseInt(in.readLine());
                int CID = Integer.parseInt(in.readLine());
                if (postComment(text, UID, CID))
                    out.println("true");
                else
                    out.println("false");
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;

        case 10:
            try {
                String username = in.readLine();
                String oldPass = in.readLine();
                String newPass = in.readLine();
                String conf = in.readLine();
                if (Security.changePass(username, oldPass, newPass, conf))
                    out.println("true");
                else
                    out.println("false");
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;

        case 11:
            try {
                int CID = Integer.parseInt(in.readLine());
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT ipadd FROM candidate WHERE CID = " + CID + ";");
                if (rs.next())
                    out.println(rs.getString(1));
                int port = Integer.parseInt(in.readLine());
                out.write(port);

            } catch (IOException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            break;

        }
    }
}

以下是我的客户端方法(如果问题在于它们):

public class Client {
    private static Socket clientSocket;
    private final int PORT_NUM = 4373;
    private static DataOutputStream p2pout;
    private String IP;

    public Client(String IP) throws IOException {
        this.IP = IP;
        try {
            clientSocket = new Socket(IP, PORT_NUM);

        } catch (Exception e) {
            System.err.println("Cannot connect to the server, try again later.");
            System.exit(1);
        }
    }

    public void sendCommand(int com) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(com + "");
        out.close();
        in.close();
    }

    public static boolean SignIn(String Username, String password) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(1);
        out.println(Username);
        out.println(password + "\n");
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean SignUp(String Username, String name, String email, String password, String conf)
            throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(2);
        out.println(Username);
        out.println(name);
        out.println(password);
        out.println(email);
        out.println(conf);
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean ForgetPass(String email) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(3);
        out.println(email);
        String reply = in.readLine();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean ForgetPass2(String code) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(3);
        out.println(code);
        String reply = in.readLine();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean ForgetPass3(String newpass, String conf) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(newpass);
        out.println(conf);
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean nominate(int CID, int UserID) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(4);
        out.println(CID + "");
        out.println(UserID + "");
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean vote(int cid, int UID) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(5);
        out.println(cid);
        out.println("" + UID);
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean postcomment(int CID, String text, int UID) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(7);
        out.println(text + "");
        out.println(UID + "");
        out.println(CID + "");
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public static boolean Changepass(String Username, String oldpass, String newpass, String conf) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(10);
        out.println(Username);
        out.println(oldpass);
        out.println(newpass);
        out.println(conf);
        String reply = in.readLine();
        out.close();
        in.close();
        if (reply.equals("true"))
            return true;
        else
            return false;
    }

    public String getIPAddress(int cid) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        out.println(11);
        out.println(cid + "");
        String inetAddress = in.readLine();
        out.close();
        in.close();
        return inetAddress;
    }

    public int getServerChatPort() throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        int port = Integer.parseInt(in.readLine());
        out.close();
        in.close();
        return port;
    }

    public static void connectionListener(String inetadd) {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            ServerSocket ss = new ServerSocket(0);
            Socket clientSocket = ss.accept();
            out.println(ss.getLocalPort() + "");
            Socket candSock = ss.accept();
            ChatListener cl = new ChatListener(candSock);
            cl.start();
            out.close();
            in.close();
            while (true) {
                if (ChatListener.flag == 1)
                    cl.display();
                // ^^ Displayed in GUI
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public Socket chatConnect(String inetAdd) {
        Socket soc = null;
        try {
            int port = getServerChatPort();
            soc = new Socket(inetAdd, port);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return soc;
    }

    public void send(String m) {

        try {
            p2pout.writeChars(m);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void close() throws IOException {
        clientSocket.close();
    }
}

1 个答案:

答案 0 :(得分:0)

问题的根源是每次操作后关闭套接字。那么代码关闭连接到套接字的输出流,但关闭从getOutputStream()返回的流也会关闭相关的套接字。

后续客户端发送尝试失败,因为套接字已关闭且服务器因接收操作(readLine())被中断且未收到任何数据而失败。

尝试保持客户端输出流打开。您可以创建一个类属性,如Socket或其他。