zoukankan      html  css  js  c++  java
  • TCP/IP详解 笔记十四

    TCP/IP协议(二) 

    连接的建立与终止

    tcpdump -S输出TCP报文的格式

    格式: 源>目的:标志 (标志就是tcp头部)。标识首字符意义如下:

    例如:telnet 某服务的输出(包括连接建立和终止)

    标识解释:S 1415531521:1415531521(0) win 4096 <mss 1024>

    S(SYN):代表建立一个连接

    1415531521:1415531521(0) :本次传送的首字节序号是1415531521(这里是ISN),尾字节序号是1415531521,数据长度为0字节。

    Win 4096 :窗口大小为4096字节

    <Mss 1024>:协商的最大报文长度为1024字节

    注:如果tcpdump不加-s的话,则除了SYN会打印完整的序号,后续序号输出为相对ISN的偏移量。

    连接建立过程

    连接的终止过程

    与程序状态相关

    1. 客户端应用程序退出,导致其TCP发送FIN并携带FIN序号。
    2. 服务端TCP收到FIN发送ACK,并向应用程序发送文件结束符EOF
    3. 应用程序收到结束符后,关闭其连接,导致TCP发送FIN。
    4. 客户端确认FIN。

    注:

    1. 连接建立和终止发起者总数主动打开或关闭,而对端被动打开或关闭。
    2. 建立连接需三次握手,而终止却需要四次,这是由TCP的半关闭造成的。

    超时机制

    1.500ms的计算器

    2.第一次超时为6s,第二次超时为24s

    最大报文长度

    1.MSS :TCP传到对端最大数据长度(不包括TCP首部长度)

    2.双方都通过期望的MSS值,如果一方不同意另一方的则MSS定为默认值536字节

    3.MSS选项只能出现在SYN报文段中

    4.TCP双方不在同一网络,则一般使用536作为报文最大长度。

    5.报文长度应小于路径MTU,避免分段

    半关闭状态

    1.半关闭:TCP连接的一端在结束它的发送后,还能收到对端数据。

    2.实现方法:关闭时使用shutdown ,且第二个参数值设为1,而不使用close.

    3.序列图:

    TCP协议的状态变迁图

    注意:

    1. 只有SYN_RCVD是从LISTEN状态进入时,从SYN_RCVD回到LISTEN状态才是有效的。
    2. 两个进入ESTABLISHED对应于打开连接,两个离开ESTABLISHED对应于关闭连接。

    连接打开和关闭的流程

    2MSL等待时间

    1.MSL最大报文段生存时间,而TIME_WAIT状态时2被MSL时长,又称为2MSL等待时间,这可以防止最后的ACK丢失。

    2.MSL受IP报文生存时间限制。

    3.处于2MSL的插口不可再被使用。

    4.某些试图可以通过声明SO_REUSEADDR选项,可以使用处于2MSL的插口,但TCP的原则是不允许的。

    5.处于2MSL状态的插口收到迟到的数据包会直接丢弃。因为,这些数据包会被新连接误解。

    6.2MSL的时间一般在1~4分钟。

    平静时间

    RFC793指出,TCP重启后MSL秒内不能建立任何连接,避免重用(重启ISN回归初始值)重启前处于2MSL的端口,防止迟到的报文段被新连接误解。

    FIN_WAIT_2状态

    发FIN,并收到确认的状态。可能出现无限等待情况,对端收到FIN发确认(CLOSE_WAIT)但应用程序并不关闭(不发送FIN)。一些实现通过计时器避免该问题发生,但都不符合协议规范。

    复位报文

     访问不到的端口报文

    UDP在这种情况下发送ICMP差错报文,TCP使用复位报文。

    Eg.

     异常终止一个连接

    1.通过发送复位报文,异常终止一个连接。收到RST报文段的一方将终止连接,并通知应用层连接复位。

    2.异常终止的好处:1.丢弃任何待发送数据立即发送复位报文段(FIN会等到所有排队数据发送完成),2.RST的接收方会区分另一端执行的是正常还是异常关闭。

    3.可以通过设置sock选择SO_LINGER实现异常关闭。

    检查半打开连接

    1.半打开连接:一方已经关闭或异常终止(网络断线)而另一方还不知道。

    2.只要不在半打开连接上传输数据,仍处于连接状态的一方不会检测到另一方已经出现异常。

    3.当连接另一方重置后,对收到的报文段回复RST。

    4.使用TCP的keepalive能使TCP的一端发现另一端已经取消。

    同时打开

    同时关闭

     TCP的选项

    其中无操作(kind=1)的选项用于填充,将其他选项填充到4字节边界。

    服务器设计

    呼入连接请求队列

    1.正等待连接请求的一端,有个存放完成三次握手但未被应用程序接受的固定长度队列。TCP接受一个连接是将其放入这个队列,应用层接受该连接是从该队列将其移出。

    2.应用层将指明该队列的最大长度(listen),这个值通常称为积压值(backlog),取值范围为0-5

    3.当一个连接请求(SYN报文段)进来时,TCP根据当前队列存在的连接数和积压值,来确定是否接受该连接,solaris接受的最大连接数等于积压值,而传统BSD最大连接数等于,积压值*3/2+1。注意:积压值说明的是被TCP接受但未被应用层接受的最大连接数,这个积压值与系统所允许的最大连接数,或者并发服务器能并发处理的客户数,并无影响。

    4.处于该队列的连接(完成3次握手但未被应用程序接受),对应的客户端认为建立连接完成,并开始传送数据,此时TCP服务端将数据放到缓存中。

    5.如果队列没有空间,则不理会新到的SYN报文段(新建连接),也不发送任何报文段。

  • 相关阅读:
    记录一次阻塞引发的系统超时
    2015年读书清单
    循序渐进的敏捷-每日例会
    循序渐进的敏捷-交叉测试
    对一次系统上线的思考-走出“舒适区”
    单点登录(SSO)系统的总结
    对一个同事项目的思考和总结
    关于福建出差的总结
    由错误处理引发的联想-防御式编程
    关于日志记录的总结
  • 原文地址:https://www.cnblogs.com/manziluo/p/5862969.html
Copyright © 2011-2022 走看看