检查服务器上的客户端套接字是否已关闭

时间:2015-02-25 14:39:22

标签: java sockets

如何在服务器端检查客户端是否关闭了套接字?

我有这个服务器,等待连接,然后向客户端返回10条消息:

public class SocketServidor {
    static ServerSocket serverSocket;

    public static void main(String[] args) throws Exception {
        serverSocket = new ServerSocket(5963);
        while(true) {
            final Socket socket = serverSocket.accept();
            new Thread(() -> {
                try {
                    PrintWriter out = new PrintWriter(socket.getOutputStream());
                    for (int i = 0; i < 10; i++) {
                        int valor = (int) (Math.random() * 5) + 1;
                        out.println("Você acabou de ganhar R$ "+new DecimalFormat("###,##0.00").format(valor)+"!");
                        out.flush();
                        Thread.sleep(valor*1000);
                    }
                    socket.close();
                } catch (Exception ex) {
                    Logger.getLogger(SocketServidor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }).start();
        }
    }
}

客户端只读取值,但在第五次读取时停止:

public class SocketCliente {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("localhost", 5963);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String leitura;
        int lidas = 0;
        while((leitura = in.readLine()) != null) {
            lidas++;
            System.out.println(leitura);
            if(lidas == 5){
                socket.close();
            }
        }
    }

}

问题是,当客户端关闭套接字时,即使在第五次读取之后,服务器也会不断向客户端发送消息。如何在客户端关闭服务器端的套接字时将其关闭?

1 个答案:

答案 0 :(得分:0)

PrintWriter.flush()
禁止异常 您没有看到任何异常,因为PrintWriter.flush()会禁止该异常。要在PrintWriter.println()之后检查错误状态,您可以使用PrintWriter.checkError()代替flush()。或者,您可以使用OutputStreamWriter而不是PrintWriter,然后不会禁止该异常。

  1. 使用checkError

    serverSocket = new ServerSocket(5963);
    while(true) {
        final Socket socket = serverSocket.accept();
        new Thread(() -> {
            try {
                PrintWriter out = new PrintWriter(socket.getOutputStream());
                for (int i = 0; i < 10; i++) {
                    int valor = (int) (Math.random() * 5) + 1;
                    out.println("Você acabou de ganhar R$ "+new DecimalFormat("###,##0.00").format(valor)+"!");
                    //out.flush();
                    if(out.checkError()){
                        System.out.println("Error. Break");
                        break;
                    }
                    Thread.sleep(valor*1000);
                }
                socket.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }).start();
    }
    
  2. 使用OutputStreamWriter

    serverSocket = new ServerSocket(5963);
    while(true) {
        final Socket socket = serverSocket.accept();
        new Thread(() -> {
            try {
                Writer out = new OutputStreamWriter(socket.getOutputStream());
                for (int i = 0; i < 10; i++) {
                    int valor = (int) (Math.random() * 5) + 1;
                    out.write("Você acabou de ganhar R$ "+new DecimalFormat("###,##0.00").format(valor)+"!");
                    out.write("\r\n");
                    out.flush();
                    Thread.sleep(valor*1000);
                }
                socket.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }).start();
    }