关于TCP的学习总结

1、TCP和UDP的区别

(1)TCP面向连接,UDP无连接;
(2)TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证;
(3)TCP传输速度慢;UDP速度快
(4)每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
(5)TCP对系统资源要求较多,UDP对系统资源要求较少。
(6)TCP的逻辑通信信道是全双工的可靠信道,UDP是不可靠信道。
(7)UDP没有拥塞机制,因此网络出现拥塞不会使源主机的发送速率降低。
(8)TCP首部开销20字节;UDP的首部开销小,只有8个字节;
(9)UDP面向报文。

  • 什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP; FlashFXP,用的FTP; Outlook,用的POP、SMTP; Putty,用的Telnet、SSH; QQ文件传输
  • 什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频…
    有些应用场景对可靠性要求不高会用到UDP,比如长视频,要求速率

2、TCP三次握手四次挥手

2.1 建立连接协议(三次握手)

(1)客户端发送一个带SYN标志位、seq的TCP报文到server。这是三次握手过程中的报文1。此时client进入SYN_SEND状态。
(2) server端回应client的报文,是三次握手中的第2个报文。这个报文同时带ACK(确认字符)标志、SYN标志、ack(=收到来自客户端的seq+1)、seq(server自己的)。因此它表示对刚才client SYN报文的回应。此时server进入SYN_RECV状态。
(3) 客户必须再次回应服务段一个包括ACK、ack(=来自server的seq+1)、seq(第一次握手的seq+1)的报文,这是报文段3。此时双方进入ESTABLISHED状态。
名词解释:

  • 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
  • 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
  • SYN:属于一个标志位,为1时代表这是一个连接请求(当ACK=0)或连接接受响应(当ACK=1)报文;SYN这个标志位只有在TCP建立连接时才会被置1,握手完成后SYN标志位被置0。
  • ACK:只在响应中出现。占1位,仅当ACK=1时,ack才有效。ACK=0时,ack无效。

2.2 连接终止协议(四次挥手)

因为TCP连接是全双工的,因此每一个方向都必须单独进行关闭。这原则是当一方完毕它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN仅仅意味着这一方向上没有数据流动。一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将运行主动关闭。而还有一方运行被动关闭。
流程:
 (1) 主机1发送FIN和seq。请求关闭主机1到主机2的数据传送(报文段4)。此时状态变化: 1:FIN_WAIT1
 (2) 主机2收到这个FIN。它发回一个ACK、ack(收到的seq加1)、seq(报文段5)。
这一步代表主机2同意关闭连接,但连接并没有关闭,因为主机2可能还有数据没发完,为此需要等待。此时状态变化:2:CLOSE_WAIT | 1:FIN_WAIT2
 (3) 主机2发完剩余数据,准备关闭与主机1的连接,并发送一个FIN给主机1(报文段6)。进入LAST-ACK(最后确认)状态。如果没收到主机1的回复,会进行超时重传的。
 (4) 主机1收到主机2回复,知道它的数据发送完了。于是发回ACK报文确认收到,告诉主机2你可以关了。并将ack设置为收到序号加1(报文段7)。这样一来主机2收到后就安心关闭连接了。此时状态变化: 1:TIME_WAIT | 2:CLOSED。
 这样四次挥手就完成了。不过别忘了,主机1还在TIME_WAIT状态。他需要等待2MSL的时间,如果在这段时间又收到来自主机2的FIN+ACK报文(报文段6),就会再发送ACK报文回去,直至过了2MSL且再无回音,就关掉。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指任何IP数据报能够在因特网上存活的最长时间,2MSL就是一个发送和一个回复所需的最大时间。

 
名词解释:

  • FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接

3. 一些常见的问题

  1. 为什么要进行time wait,为什么要等2MSL?
    为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。没收到确认的话,B是会超时重传这个FIN+ACK报文段的,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。
  2. 为什么连接的时候是三次握手,关闭的时候却是四次握手?
    因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,可能还有数据要传,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,是不能一起发送的。故需要四步握手。
  3. 为什么要三次握手?
    不行。因为握手是为了确认双方收发功能均正常,进而确认可以同步序列号。第一次client -> server,server可以确认client发是好的;第二次server -> client,client可以确认自己收发是好的,对方收发也是好的;第三次client -> server,server可以确认自己收发是好的,对方也是。
    为什么可以这么确认?是因为这收发之间都存在着校验。第一次server收到client的连接请求,推测其可能要发起连接,于是按规定返回了client要求的ack(收到的seq+1),并且发了自己的seq,看对方是不是真想连接;第三次client收到并返回的过程类似第二步。如此,就完成了对接。
    为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
    如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。