我在windows 7 x64上。我正在编写一个服务器,它为每个传入的连接打开一个线程--线程从连接的输入流中读取。如果套接字被关闭(),read()应该阻止并抛出异常。它不仅--只是返回- -1。如果我不关闭来自客户端的连接--只是让客户机终止--我会将连接重置为切除--但是如果我关闭()来自客户机的连接(或者只是客户机的输出流),那么服务器线程中的read()就不会抛出--只返回-1。文档在这一点上非常清楚:
public ()抛出IOException 关闭这个插座。当前在这个套接字上I/O操作中阻塞的任何线程都会抛出一个SocketException。
帮助
工作代码:
服务器:
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CloseTest {
private int port;
public CloseTest(int port) {
this.port = port;
}
void base_station_activate() {
ServerSocket baseStationListeningSocket=null;
try {
baseStationListeningSocket = new ServerSocket(this.port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException ex) {
}
main_server: while (true) {
try {
Socket clientSocket = baseStationListeningSocket.accept();
BaseStationClientHandler ch = new BaseStationClientHandler(clientSocket);
Thread myThread = new Thread(ch);
myThread.start();
} catch (IOException ex) {
System.exit(1);
} // main_server
finally {
// baseStationListeningSocket.close()
}
}
}
public static void main(String args[]){
CloseTest bs = new CloseTest(8082);
bs.base_station_activate();
}
public class BaseStationClientHandler implements Runnable {
private final Socket clientSocket;
private BaseStationClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
String debug_message = null;
try {
InputStream in = clientSocket.getInputStream();
// read message and respond
String s = "";
char x;
int r;
server: while (true) {
try {
while ((r = in.read()) != (int) '%') {
if (r == -1) {
debug_message = "Stream/socket .closed() - exception not thrown (WHYYYYY ????) by client";
System.out.println(debug_message);
break server;
}
x = (char) r;
s += x;
}
System.out.println(s);
} catch (SocketException socketException) {
System.out.println(socketException.getLocalizedMessage()); // if connection reset (but not if Stream/socket .closed()) read throws !!!!!
debug_message = "socket_reset";
break server;
}
s = "";
} //server
} catch (IOException ex) {
System.out.println("IOexception in client handler - check if thrown by read");
} finally {
try {
clientSocket.close();
} catch (IOException ex) {
}
}
}
}
}客户:
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Vector;
public class CloseTestClient {
public CloseTestClient(int port, String ipAddress){
Vector<Socket> connections = new Vector<Socket>();
try {
for(int i=0;i<20;i++){
Socket connection = new Socket(InetAddress.getByName(ipAddress), port);
connections.add(connection);
OutputStream out = connection.getOutputStream();
out.write( ("CONNECT#"+(i+1)+"#1%").getBytes());
System.out.println("[CloseTestClient SENT]:"+"CONNECT#"+(i+1)+"#1%");
Thread.sleep(1000); // to be sure the server threads are blocked in the read()
// connection.close(); // if I comment this out I see the connection reset message from the server when this main terminates
// commented it out finally and moved the closing at the end to be sure the server threads are blocked in read()
}
} catch (Exception ex) {
ex.printStackTrace();
}
finally{
// if I comment *for* out I see the "connection_reset" message from the server when this main terminates
for (Socket c : connections){
try{
c.close();
}catch(Exception ex){
}
}
}
}
public static void main(String args[]){
System.out.println("CloseTestClient run !");
new CloseTestClient(8082,"127.0.0.1");
}
}发布于 2011-11-30 22:51:52
您所指的文档适用于该机器上的线程,而不是远程线程。如果套接字X上有线程A read()'ing,而同一进程的线程B关闭socket X,那么线程A的读调用将引发异常。
当本地机器上的套接字是close ()d时,远程机器可以确定不会有更多的数据通过套接字返回-1 (请参阅InputStream的read()文档)。这是当您显式地关闭客户机上的连接时发生的情况。服务器知道没有更多的数据会来,所以read()很高兴地返回-1。没有异常情况。
我猜想,当您让客户端终止而不调用套接字上的close()时,JVM或OS发送的是TCP,而不是很好地关闭连接(发送TCP )。这将导致对服务器的read()调用引发异常。
https://stackoverflow.com/questions/8334045
复制相似问题