19connection reset rst fin linger(一)

 

package com.jds.test.bio.p11;

/**
 *
 * Created by joyce on 2019/11/26.
 */


import java.net.InetSocketAddress;
import java.net.Socket;


public class Client {

    public static final int PORT = 12123;
    public static final int BUFFER_SIZE = 1024;

    public static void main(String []f) throws Exception {
        new Client().client();
    }

    //客户端代码
    public void client() throws Exception{
        final String s1 = "49.235.75.155";// tx
        final String s2 = "localhost";
        byte[] buffer;
        Socket s = new Socket();

        /**
         * 决定rst or fin
         */
    //    s.setSoLinger(true, 0);
        s.bind(new InetSocketAddress(8888));
        s.connect(new InetSocketAddress(s1,PORT));
        int i = s.getInputStream().read(buffer = new byte[BUFFER_SIZE]);
        System.out.println(new String(buffer,0,i));

        /**
         * 程序自然结束,close
         */
    }
}

 

package com.jds.test.bio.p11;

/**
 *
 * Created by joyce on 2019/11/26.
 */
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static final int PORT = 12123;
    public static final int BUFFER_SIZE = 1024;

    public static void main(String [] f) {
        try {
            new Server().server(f.length == 0 ? "1":f[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //服务端代码
    public void server(String flag) throws IOException, InterruptedException{
        System.out.println(flag);
        ServerSocket ss = new ServerSocket(PORT);
        while(true) {
            Socket s = ss.accept();

            s.getOutputStream().write("hello ".getBytes());
            s.getOutputStream().flush();

            Thread.sleep(5000);

            // 没什么鸟用
            System.out.println(s.isClosed());

            if("2".equals(flag)) {
                s.getOutputStream().write(1);
                s.getOutputStream().flush();
            }

            if("3".equals(flag)) {
                s.getOutputStream().write(1);
                s.getOutputStream().flush();
                Thread.sleep(2000);
                s.getOutputStream().write(2);
            }

            while (s.getInputStream().read(new byte[BUFFER_SIZE]) != -1) {
                ;
            };
            /**
             * 显示close,发出fin包
             */
            s.close();
        }
    }
}

 

 

(一)false read

[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar
1
false

 

5s内

JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 FIN_WAIT_2

5s后
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 TIME_WAIT

 

(二)true read

^C[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar
1
false
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:127)
at com.jds.test.bio.p11.Server.server(Server.java:45)
at com.jds.test.bio.p11.Server.main(Server.java:18)

 

netstat 无

 

(三)false write 服务端入参2

[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 2
2
false

 

5s内

JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 FIN_WAIT_2

5s后
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123

 

 

(四)true write 服务端入参2
^C[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 2
2
false
java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:115)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at com.jds.test.bio.p11.Server.server(Server.java:41)
at com.jds.test.bio.p11.Server.main(Server.java:18)

 

netstat 无

 

 

(五)false write write 服务端入参3

[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 3
3
false
java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at com.jds.test.bio.p11.Server.server(Server.java:49)
at com.jds.test.bio.p11.Server.main(Server.java:18)

JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 FIN_WAIT_2 
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123

 

 

A 本地 mac client

B centos 7 server

 

结论:

1 进程退出,tcp连接还在

2 A fin B, B read, no exception, fin_wait2(within 5s)->time_wait(after 5s)

3 A rst B, B read, Connection reset,netstat none(within and after 5s)

4 A fin B, B write, no exception, A rst B, fin_wait2(within 5s)->none(after 5s)

5 A rst B, B write, Connection reset, netstat none(within and after 5s)

6 A fin B, B write, no exception, A rst B, B write again, Broken Pipe, fin_wait2(within 5s)->none(after 5s)

7 rst后,netstat nothing,没有time_wait fin_wait,也无需ack

8 一三五情况中程序sleep,但是tcp内核发出应对fin的ack

9 socket.isClosed没用

 

lingerrstfin.zip

 

 

 

引子:

第(三)种情况是典型的4次挥手,为什么会出现client拒绝处理server最后的那个包,直接发出RST,在下一节中我们讨论

posted on 2019-12-18 22:59  silyvin  阅读(206)  评论(0编辑  收藏  举报