一、传输层协议:
1.TCP 可靠传输
面向连接:数据传输之前需要先建立连接,传输成本相对较高,通过重传机制实现数据纠错,具备流控制功能。
什么是流控制:就是主机1给主机2发送数据的过程中,可能一次发送的数据量较大,那么主机2告诉主机1,自己的缓冲区没有足够的能力一次处理这么多数据,那么下一次发送数据的时候,主机1发送的数据量就相应的减少
2.UDP 不可靠传输
无连接:不需要事先建立连接,传输成本相对较低
两种传输有各自的应用领域
二、TCP和UDP包头的对比
从图中可以看出TCP包头是20字节,UDP包头是8字节,TCP的字段比UDP的字段多一些
TCP是通过确认机制(acknowledgement number)和序列号(sequence number)来保证数据传输的可靠性,在UDP里面没有这两个字段。
TCP和UDP都有校验和字段(checksum),错误检测能力。但是UDP没有确认机制和序列号,所以它没有数据纠错(数据重传)能力。
三、完整的TCP包头信息
1.两个16bit的端口号,分别是源端口、目标端口
不同的端口号代表了不同的应用,类似于电视的频道,通过端口号可以判断上层的应用是什么,例如80,上层就是http服务
知名端口:0-1023
非知名端口:1024-65535
2.32位的序列号
3.32位的确认号
2和3来保证tcp传输的可靠性
确认号有两个作用,第一用于确认,第二用于表示这是一个请求,还有一个作用就是通知请求方,下一次发送信息过来的时候,包头里的 序列号 应该从这个数字开始。
4.4bit的包头信息-保留字段-代码位,其中代码位包含了一些比较复杂的信息
前面说TCP传输可靠,那么它的可靠性是如何保障的,在这里分析一下(TCP三次握手)。
图中的信息比较复杂,其中小框框里的东西叫代码位,不同的代码位有不同的作用,下面看看三次握手的具体过程,假设是 a 主机和 b 主机进行通信。
a) a主机首先设置自己的 syn=1(表示同步请求) ,sequence number=100(随机数,这里假设序列号是100),CTL=SYN(代码位整体表现为SYN),把包头发给主机b,(000000010),第一次握手完毕。
b) b主机收到信息后,为了表明自己已经收到请求,那么b主机要给a主机做出响应,那么b主机把自己的包头信息设置为这样: syn=1(b给a发信息也相当于一次请求,所以把自己的请求信息设置为1),小ack=1(syn和ack都为1,表示对a主机请求的确认),sequence number=300(同上),acknowledgement number=101(确认号设置为101,这里不是随机数,是a主机序发送的序列号+1,详见上面的第三步),CTL=SYN.ACK(代码位整体表现为SYN和ACK), 把这些设置好的包头信息发送给主机a,第二次握手完成。
c) 主机b如何知道自己设置好的响应信息发送到了主机a,所以还需要第三次握手, 这时候主机a为了表明自己受到了主机b的响应,把自己包头设置为syn=0(之前已经发过同步请求,此时不再不再需要发送同步请求了),sequence number=101(从两方面判定,1:上次发送的序列号为100,这次就是101, 2:b主机要求本次的序列号是101),CTL=ACK(代码位表现为ACK),发送给主机b,第三次握手完成。
一旦建立连接之后,每次通信的时候,代码位的ack都是1,表示以后接收方收到tcp信息都要进行确认,保证tcp传输的可靠性,如果不进行确认,那就违背了tcp传输的可靠性。
5.16bit的窗口大小
接第四步,建立连接之后 ack被设置为1,那么每次通信都需要确认,那么交互非常频繁,接收方每次收到数据都要告诉请求方,进行确认 来保证数据的完整新。
通常情况下,窗口大小为1,表明发送一个请求,响应一次(固定窗口),现在把窗口大小设置为3,收到三次的数据,再回答一次。
意外:如果接收方的缓冲区不足,不能一次容纳请求方的3次请求的数据量,这时候接收方会把自己的窗口大小下降为2,并且让发送方从丢失的那个包重新发送数据。
6.16bit的校验和
7.16bit的紧急指针
8.可选项
9.封装的上层数据
四、TCP连接的关闭
1.正常关闭
主机a和主机b通信完成后,需要正常关闭连接
1.主机a发送一个代码位fin=1的包头到b主机。
2.主机b收到后,向a主机发送一个代码位ack=0的响应,表示认可/同意a的关闭请求。(前面完成三次握手后,ack一直保持为1)
3.主机b同时在发送一个代码位fin=1的包头到主机a
4.主机a发送确认关闭会话的请求到主机b,完成关闭连接
2.非正常关闭
当收到代码位rst=1的包头的时候,主机会立马重置tcp连接。
五、保持存活
当两台主机建立连接后,如果在短暂的时间内不进行数据传输,连接不回立马被断开,TCP通过keepalive信息保持TCP连接的维持。
这个在我们b/s开发中最常见到,例如请求一个网址之后,用firebug就能看到很多个连接信息, 以前总听说HTTP/1.1使用的是长连接,效率较高,听的云里雾里的,现在终于明白了。因为它不回每次请求都关闭连接嘛,效率自然是高了。同时也可以看到请求头信息中有一行为:Connection: keep-alive.
六、总结
看来动手学学还是很有必要的,以前看过很多人写的tcp三次握手、四次挥手 感觉很高上大,可自己就是看不懂,非常恼火。现在终于通过自己查找资料明白了其中的原理。
记得有一次去一个特别大的公司面试,老汉说就问一个问题:在浏览器中输入一个网址回车,看到网页信息后,这中间都做了些什么? 当时就楞了 不知道说什么, 后来自己也查过资料 可其中有些步骤就是看不懂。现在对整个过程中的这一小环节终于有所了解了。
这个系列的资料比较长,还得静下心来,慢慢学习。
感谢无私奉献的前辈们贡献的资料。