20connection reset rst fin linger(二)【yetdone】

在上一节中,我们发现(三)情况是典型的4次挥手场景,却没有成功,这不是与4次挥手相悖么

原来,https://www.cnblogs.com/exmyth/p/8204724.html

前面说到出现“Connection reset”的原因是服务器关闭了Connection[调用了Socket.close()方法]。大家可能有疑问了:服务器关闭了Connection为什么会返回“RST”而不是返回“FIN”标志。原因在于Socket.close()方法的语义和TCP的“FIN”标志语义不一样:发送TCP的“FIN”标志表示我不再发送数据了,而Socket.close()表示我不在发送也不接受数据了。问题就出在“我不接受数据” 上,如果此时客户端还往服务器发送数据,服务器内核接收到数据,但是发现此时Socket已经close了,则会返回“RST”标志给客户端。当然,此时客户端就会提示:“Connection reset”。详细说明可以参考oracle的有关文档:http://docs.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html

 

socket的close!=tcp fin,不能用于验证tcp 4次挥手,那么什么可以呢

  1. Use shutdownOutput(). This method has the same effect as close() in that a FIN is sent to indicate that this peer has finished sending, but it is still possible to read from the socket until such time as the remote peer sends a FIN and end-of-file is read from the stream. Then the socket can be closed with Socket.close().

 https://blog.csdn.net/zhougb3/article/details/80076857

该文从文件描述符论述了shutdown与close的区别

 

我们将client端程序稍加改动:

 

        int flag = 22;
        if(flag == 0) {

        } else if(flag == 11) {
            s.close();
        } else if(flag == 12) {
            s.shutdownOutput();
        } else if(flag == 21) {
            s.close();
            Thread.sleep(10000);
        } else if(flag == 22) {
            s.shutdownOutput();
            Thread.sleep(10000);
        }

 

0 11 12 21 都与上一节(三)一样,证明

1)close发fin包,而且不再接收

2)自然进程结束就是close

3)自然进程结束会覆盖shutdownOutput,导致不再接收

只有22 显示了客户端没有直接回绝四次挥手中服务端fin前一次psh,还发出了ack

4)证明了shutdownOutput会且只会发fin包,不会拒绝接收

 

但不知为何之后双方互发rst ??5次里面有一次没有互发rst

 

四次挥手.zip

posted on 2019-12-19 22:55  silyvin  阅读(160)  评论(0编辑  收藏  举报