18读缓冲区(滑动窗口)耗尽与write阻塞、拆包、延迟(四)linger

读缓冲区(滑动窗口)耗尽与write阻塞、拆包、延迟(三)中,程序退出了,tcp协议还在自己跑,关键是SO_LINGER参数

默认-1,则会等发送缓冲区发完才发压箱底的fin,true时,会直接关闭连接,本文予以验证

    //    s.setSendBufferSize(BUFFER_SIZE);

        /**
         * 禁用nagle,可连续发包
         */
        s.setTcpNoDelay(true);

        /**
         * 重要参数
         */
        System.out.println(s.getSoLinger());
        s.setSoLinger(true, 0);

 

由于发送缓冲区默认巨大,客户端输出:

131072
131072
-1
send + 0
send + 1
send + 2

。。

send + 99

Process finished with exit code 0

 

服务端输出:

43690
/183.192.17.180:25716
0
1
2
3
4
5
6
7
8
9
10
Exception in thread "main" 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.p6.Server.server(Server.java:59)
at com.jds.test.bio.p6.Server.main(Server.java:35)

 

 

结论:

1 linger默认false

2 close socket时,发fin还是rst,什么时候发,发之前是否先等缓冲区全部发送完,由tcp协议Linger参数控制

3 linger为true时,显式或隐式(程序正常退出)close socket,直接RST包,无视发送缓冲区的待发送内容,然后就没有然后了

4 对端收到rst包,无需ack

5 一端rst另一端,另一端再read,会报connection reset

 

 

lingertrue.pcap.zip

posted on 2019-12-17 23:59  silyvin  阅读(258)  评论(0编辑  收藏  举报