tcp协议里,关闭这个动作是双向的。
客户端关了不代表服务器关了,服务器关了不代表客户端关了;
客户端关了服务器不一定知道,服务器关了客户端不一样知道;(这里说的是close这个动作,不是服务器宕机,宕机客户端是有反应的)你那种情况是,客户端关了,close以后向服务器发送一个fin,同时在等待服务器返回ack和fin,但是服务器收到fin以后,由于无法通知应用层(应用层不知道客户端已经完蛋了),所以服务器没有主动close,发送fin,所以你看到的流还是开的

解决方案 »

  1.   


    但是我自己写一个Socke程序。 如果将客户端在中途关掉。 那么服务端就抛出java.net.SocketException: Connection reset异常了。下面的程序,如果将Client在运行时中途关掉。 那么Server端会抛出异常package test;import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class Server {

    public static void main(String[] args) throws Exception {

    ServerSocket server = new ServerSocket(1213) ;
    Socket client = server.accept() ;

    InputStream is = client.getInputStream() ;

    byte[] b = new byte[1024] ;
    int len = -1 ;
    while((len = is.read(b)) > 0){
    System.out.print(new String(b , 0 , len));  
    }

    }
    }package test;import java.io.OutputStream;
    import java.net.Socket;public class Client {

    public static void main(String[] args) throws Exception{

    Socket socket =  new Socket("localhost" , 1213) ;

    OutputStream os = socket.getOutputStream() ;

    for (int i = 0; i < 10; i++) {
    os.write(String.valueOf(i).getBytes());
    os.flush();
    Thread.sleep(1000);  
    }
    os.close(); 
    }}
      

  2.   


    但是我自己写一个Socke程序。 如果将客户端在中途关掉。 那么服务端就抛出java.net.SocketException: Connection reset异常了。下面的程序,如果将Client在运行时中途关掉。 那么Server端会抛出异常package test;import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class Server {

    public static void main(String[] args) throws Exception {

    ServerSocket server = new ServerSocket(1213) ;
    Socket client = server.accept() ;

    InputStream is = client.getInputStream() ;

    byte[] b = new byte[1024] ;
    int len = -1 ;
    while((len = is.read(b)) > 0){
    System.out.print(new String(b , 0 , len));  
    }

    }
    }package test;import java.io.OutputStream;
    import java.net.Socket;public class Client {

    public static void main(String[] args) throws Exception{

    Socket socket =  new Socket("localhost" , 1213) ;

    OutputStream os = socket.getOutputStream() ;

    for (int i = 0; i < 10; i++) {
    os.write(String.valueOf(i).getBytes());
    os.flush();
    Thread.sleep(1000);  
    }
    os.close(); 
    }}
    你这个是主动关的,主动关时客户端应该会发送通信结束的协议到服务端,然后服务端做结束通信的工作,释放资源。
    而浏览器是异常关闭,关闭时浏览器应该是没有发送通信结束的协议到服务端的,服务端觉得客户端并没有断线,所以服务端的输出流还是打开的。
    这么是我的理解,也不知道对不对。
      

  3.   


    但是我自己写一个Socke程序。 如果将客户端在中途关掉。 那么服务端就抛出java.net.SocketException: Connection reset异常了。下面的程序,如果将Client在运行时中途关掉。 那么Server端会抛出异常package test;import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class Server {

    public static void main(String[] args) throws Exception {

    ServerSocket server = new ServerSocket(1213) ;
    Socket client = server.accept() ;

    InputStream is = client.getInputStream() ;

    byte[] b = new byte[1024] ;
    int len = -1 ;
    while((len = is.read(b)) > 0){
    System.out.print(new String(b , 0 , len));  
    }

    }
    }package test;import java.io.OutputStream;
    import java.net.Socket;public class Client {

    public static void main(String[] args) throws Exception{

    Socket socket =  new Socket("localhost" , 1213) ;

    OutputStream os = socket.getOutputStream() ;

    for (int i = 0; i < 10; i++) {
    os.write(String.valueOf(i).getBytes());
    os.flush();
    Thread.sleep(1000);  
    }
    os.close(); 
    }}
    你如果主动关,tcp层会向服务器发一个复位报文(TCP:R),服务器就知道你异常退出了,抛出异常结束连接。其实你不必纠结浏览器的行为,它的行为封装起来了你看不到,你熟悉协议底层的原理就好了。比如你看到你的流还是打开的状态,你可以看下netstat查下端口的状态,如果端口的状态还是ESTABLISHED,说明客户端的连接只是发送了fin,在等待服务器close
      

  4.   

    客户端请求到Servlet后客户端关闭连接,那么在TCP层是会知道这件事(因为TCP需要ACK确认对方状态,当断开后服务器会不能收到对应包,所以认为客户断开),并且会标记状态,而在Servlet中如果没有调用连接相关的功能的话还不会知道,直到调用连接后,才会报出异常。
      

  5.   

    浏览器与web服务器之间是基于http协议通讯的,当然了http协议的底层实现还是TCP/IP协议.