检查客户端套接字是否在服务器上关闭
Check if client socket is closed on the server
如何在服务器端检查客户端是否关闭了套接字?
我有这个服务器,它等待连接然后 return 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();
}
}
}
}
问题是,即使在第五次读取之后,当客户端关闭套接字时,服务器仍继续向客户端发送消息。如何在客户端关闭套接字时关闭服务器端的套接字?
异常被 PrintWriter.flush()
抑制
您看不到异常,因为 PrintWriter.flush() 抑制了异常。要检查 PrintWriter.println()
之后的错误状态,您可以使用 PrintWriter.checkError()
而不是 flush()
。或者,您可以使用 OutputStreamWriter
而不是 PrintWriter
,这样异常就不会被抑制。
有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();
}
带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();
}
如何在服务器端检查客户端是否关闭了套接字?
我有这个服务器,它等待连接然后 return 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();
}
}
}
}
问题是,即使在第五次读取之后,当客户端关闭套接字时,服务器仍继续向客户端发送消息。如何在客户端关闭套接字时关闭服务器端的套接字?
异常被 PrintWriter.flush()
抑制
您看不到异常,因为 PrintWriter.flush() 抑制了异常。要检查 PrintWriter.println()
之后的错误状态,您可以使用 PrintWriter.checkError()
而不是 flush()
。或者,您可以使用 OutputStreamWriter
而不是 PrintWriter
,这样异常就不会被抑制。
有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(); }
带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(); }