TCP/IP 笔记

TCP的服务:

1.TCP面向连接的,可靠字节流的服务
2.面向连接的,意味着在交换数据前需要建立通信连接
3.TCP面向双方的,意味着不能进行多播和广播的。(UDP可以广播多播)

TCP的可靠性:

1.应用时间被分割为TCP认为最合适的发送的数据块(TCP拆包粘包)
2.TCP发送一个报文段的时候,会启动一个定时器,等待目的端一个确认。如果不能及时收到一个确认将会重发。
3.TCP接受端接收到一个消息后,它将会发送一个确认。这个确认不是立即发送的,会等几分之一秒。因为立即发送也是消耗资源的,比如添加ip数据报的头,以太网的帧头部也是消耗时间的。等待是为了看过一会是否有其他数据需要发送,如果有将顺带的一起发送过去。
4.由于IP数据报为TCP的下一层,TCP是通过IP数据报来进行传输。IP数据报传输的时候有可能会乱序。所以TCP报文也会乱序。如果有必要,TCP会对收到的数据进行重排序并交给应用层。
5.IP数据报会出现重复传输,TCP会丢弃重复的数据。
6.流量控制。TCP的双方都有一个缓冲区。TCP接受端只允许发送端发送缓冲区可用大小内的数据。这将避免接受数据较慢的应用出现缓冲区溢出。

字节流服务:

TCP不在字节流中插入任何标识符。所以TCP并不知道多少个字节为一个包,有时传20个字节有时传40个字节。接受端可能30字节接受一次,再30个字节接受一次。当然数据的顺序最后是可以保证的。因此我们在网络编程中需要构建一个私有的编解码器。比如Netty里的基于长度的解码器。

TCP不对报文进行任何解释行为。发送什么就接受到什么

报文结构

TCP/IP 笔记_第1张图片
1.源目端口:用来查找收发的应用程序。源目ip,源目端口可以确定互联网中每一个TCP连接的双方。
2.序号:用于确认数据的长度。比如发送100个字节数据,则初始seq+100。
3.确认序号:ACK标志位为1才有效。比如发送端发送100个字节数据,则初始seq+100,那么接受端发送的ack为seq+100+1,表示我接受端对你发送端的第101个数据感兴趣,那么发送端继续发送101个数据即可,所以ack是用来确定下一个需要发送的数据位点。一旦建立连接确认序号与标志位ACK总是被设置值的,所以发送ACK就是一个日常操作,无需额外的代价。
4.4位首部长度(tcp数据偏移量):表示tcp数据部分距离tcp报文首部的距离
5.保留位(6位):一般置为零。
6.16位滑动窗口:告诉接受端发送方的缓冲区大小
7.16位校验和:TCP报头和TCP报文数据段经过计算得到的一个校验和,由接受端进行校验。
8.紧急指针:当URG为1时有效。和顺序号字段中的值相加表示紧急数据最后一个字节的序号
9.选项:选项为可选字段,比如最常见的MSS(最大报文段长度Maximum Segment Size)在建立连接时的两次SYN中协商,获取双方中最小的值。
10.数据:应用层的数据,可选比如三次握手中就没有。

TCP没有“选择确认”和“否认”的滑动窗口协议。
没有选择确认:
TCP/IP 笔记_第2张图片
否认:接收到有问题的数据,之后继续返回之前的ACK,但是不会告诉失败的原因
TCP/IP 笔记_第3张图片

TCP六个标志位:

URG:标识紧急指针位有效 (基本上不用)
ACK:标识确认序号有效 (一般建立连接后发送数据都设置为1)
PSH:表示接受方应该尽快把这个报文段交给应用层
RST:重新建立连接
SYN:同步序号,用来发起连接(三次握手中前两次需要建立双向连接会置为1)
FIN:发送端完成发送任务

三次握手以及四次挥手

TCP/IP 笔记_第4张图片
握手:
1.C端首先主动打开,发送报文 SYN标志为1表示建立连接,seq=X,x实际为当前时间的初始序列号ISN+1(初始序列号会根据不同的操作系统,以指定的频率自增)
2.S端接受到连接返回ack。此时会等待S端的SYN报文一起发送并不是立即发送。SYN标志位为1,序列号seq为Y(S端的ISN+1),ACK标志位置1,ack为C端的序列号+1即 X+1。
3.C端接受到ack和服务端的SYN。向服务端返回ACK。ACK标志位置为1,seq为上一次的ack(因为ack表示接下来需要发送的序列号)即X+1,ack=Y+1。

挥手。
1.C端主动关闭,发送报文进入FIN_WAIT1状态,等待FIN的ack。 FIN标志位置为1,seq=u(u就是上次发送的数据序列号+1也就是上次接受到的ACK)
2.S端立即返回一个ack,同时进入CLOSE_WAIT状态,等待应用程序确认。ACK置为1,seq=v,ack=u+1。
3.C端接受到ACK,进入FIN_WAIT2等待服务端关闭报文。
4.S端应用程序确认完毕,发送FIN报文。进入LAST_ACK状态(图没画全)。由于处于半关闭状态,所以S端可能还发送了数据所以syn=w,FIN为1,ACK为1,ack为u+1。
5.C端接受到FIN,进入TIME_WAIT状态,并发送ACK。 ACK为1,ack=w+1,seq=u+1(因为上次报文的ack就是u+1)。
此时TIME_WAIT状态需要等待2MSL(Maximum Segment Life 最长报文段寿命)。因为有可能最后的ACK丢失了,导致S端资源未释放。此时S端会重发一次FIN,等待确认。 2倍是因为 一次ACK(丢失了)此时S端等待1MSL,1MSL内未接受到重发一次FIN,此时FIN会在1MSL内到达C端。总共消耗在2MSL内。

滑动窗口

待补充

你可能感兴趣的:(网络编程)