1)、TCP状态转移解释(为什么先解释一下呢?你说为什么?废话太多了!NO,因为废话多点才能更好的理解啊~)

         • CLOSED  阻塞或关闭状态,表示主机当前没有正在传输或者建立的链接

         • LISTEN  监听状态,表示服务器做好准备,等待建立传输链接

         • SYN RECV  收到第一次的传输请求,还未进行确认

         • SYN SENT  发送完第一个SYN报文,等待收到确认

         • ESTABLISHED  链接正常建立之后进入数据传输阶段

         • FIN WAIT1  主动发送第一个FIN报文之后进入该状态

         • FIN WAIT2  已经收到第一个FIN的确认信号,等待对方发送关闭请求

         • TIMED WAIT  完成双向链接关闭,等待分组消失

         • CLOSING  双方同时关闭请求,等待对方确认时

         • CLOSE WAIT  收到对方的关闭请求并进行确认进入该状态

         • LAST ACK  等待最后一次确认关闭的报文。

2)、 TCP的三次握手

TCP作为一种可靠传输控制协议,其​核心思想​:既要保证数据可靠传输,又要提高传输的效率,而用​​次恰恰可以满足以上两方面的需求!

 TCP的三次握手_数据

         • ​第一次握手:​建立连接。客户端发送连接请求报文段,并将syn(标记位)设置为1,Squence Number(数据包序号)(seq)为i,接下来等待服务端确认,客户端进入SYN_SENT状态(请求连接);

         • ​第二次握手:​服务端收到客户端的  SYN 报文段,对 SYN 报文段进行确认,设置 acl(确认号)为 i+1(即seq+1 ; 同时自己还要发送 SYN 请求信息,将 SYN 设置为1, seq为 j。服务端将上述所有信息放到 SYN+ACK 报文段中,一并发送给客户端,此时服务器进入 SYN_RECV状态。

         • ​第三次握手:​客户端收到服务端的 SYN+ACK(确认符) 报文段;然后将 ACK 设置为 j+1,向服务端发送ACK报文段,这个报文段发送完毕后,客户端和服务端都进入ESTABLISHED(连接成功)状态,完成TCP 的三次握手。

TCP的三次握手_服务端_02

那就换个说法:第一次握手第一台计算机会发送一个1。第二次握手如果第二台计算机收到然后就会+1返回去说我收到了再发一个1。第三次握手第一台计算机会收到第二台计算机返回的2证明第二台计算机已经收到了,然后再将第二台计算机发的1 加1,意思是说我要开始发数据了。

3) 、TCP报文格式以及连接对象半路丢失怎么办

TCP的三次握手_网络协议_03

    • 源端口和目的端口:各占2字节,存储源端口号和目的端口

         • 序号seq:占4字节,表示的范围就是整形的范围[0~2^32]。序号使用在给数据部分每个字节进行编号的,编号方式是mod 2^32 。

         • 确认号ack:占4字节,范围也是无符号整数的范围。使用在对端传输给我的数据最后一个字节序号,例如A传输给B 101—500,此时B返回的确认号一定是小于等于501的。当B段正确接收数据之后才会返回确认号,换句话说确认号之前的数据已经全部接收。

         • 数据偏移:占4bit,数据偏移很多人很容易想到是不是表示数据的长度,那就错了。偏移嘛,指的是TCP起始位置到数据部分的起始位置的偏移,也就是TCP首部的长度。

         • 保留:占6bit,保留字段顾名思义,就是为今后使用,默认置为0。

         • 紧急URG控制位:占用1bit,URG=1,表示紧急指针有效,此时tcp数据优先传输。相当于生活中的紧急通道,特殊情况时使用。在网络中也会有特殊情况,例如,发送一个很长的程序在远程服务器上运行,此时发现程序有bug,需要中断运行,因此我们从键盘输入Ctrl c,假如不使用紧急数据,需要在缓冲区里排队,都知道是bug了,还要排队,这怕是要出锅啊。此时使用紧急数据传输,不需要排队,直接中断程序是不是更符合我们的预期。需要注意一点是,即使窗口为0时,也可以发送紧急数据。

          如何使用紧急URG控制位,在socket编程中send函数flag参数    

          send(int socket, const void *buffer, size_t length, int flags);

         flags参数传MSG_OOB宏时,表示此时有紧急数据。MSG_OOB是个宏

        • 确认ACK:占1bit,当ACK=1时生效。TCP有条硬性规定,当建立链接成功后所有传输的数据报文都必须把ACK置为1。

        • 推送PSH:占1bit,发送方把PSH置为1时 会立即发送该数据包,接收方收到PSH=1的报文会立即处理交付给应用层处理。是不是感觉和URG很像,其实还是有些区别的。


//两者相同点:
URG与PSH两者都使用于紧急处理的情况,用来快速传输紧急数据。
 
//两者不同点
URG置为1时,对于发送发,“带外数据”与正常情况下应该发送的消息数据一起,封装成数据报发送,省去了在队列中等待的时间。
在接收方,解析报文后,获取数据之后还是要放在缓存区中,等待满了之后在向上往应用层交付。
PSH置为1时,对于发送方,表明这些数据不需要等向下发送的缓存区满,立刻封装成报文,发送,省去了等待发送缓存区到达满的状态的时间。
在接收方,也不需要等接受缓存区满,直接向上交付给应用层。


     • 复位RST:占1bit,当RST=1时,TCP会主动释放链接,两种情况会用上。TCP出现严重差错时,会主动释放连接,重建链接,传输数据。遇到非法报文或者拒绝连接时会把RST置为1。

        • 同步SYN:占1bit,同步控制位,用来在传输连接建立时同步传输连接序号。SYN=1时,表示这是一个连接请求或连接确认报文。SYN=1,ACK=0,表明这是一个连接请求数据段,如果对方同意建立连接,则对方会返回一个SYN=1、ACK=1的确认。

        • FIN控制位:占1bit,用于释放一个传输连接。FIN=1时,表示数据已全部传输完成,发送端没有数据要传输了,要求释放当前连接,但是接收端仍然可以继续接收还没有接收完的数据。FIN=0,正常传输数据。

        • 窗口大小:占16bit,2byte,用于表示发送方可以接受的最大数据大小。该窗口是动态变化的,用作流量控制时使用。

        • 检验和:占16bit,2byte,用于对TCP头部,伪头部,数据三个部分进行校验。

        • 紧急指针:占16bit,2byte,用于记录紧急数据的末尾在数据段中的位置。当URG=1时,该指针才生效。

        • 可选项:可选项最长可达40byte,是可选的,可以没有。当可选项不存在时,TCP头部长度为20byte。可选项可以包括窗口缩放选项(Window ScaleOption,WSopt)、MSS(最大数据段大小)选项、SACK(选择性确认)选项、时间戳(Timestamp)选项等。

        • 数据:TCP数据部分,由应用层应用程序提交的数据。