TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。
面向连接:三次握手
可靠性:确认、重传、流控、排序
1、源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
2、序列号,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;
3、确认号(起到一个记录的作用),占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
4、数据偏移,也就是包头长度,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远;
5、保留字段,占6位,保留今后使用,但目前应都为0,QOS中匹配保留字段来达到优先通过的效果。
6、标志位字段
(1)紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
(2)确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
(3)推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
(4)复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
(5)同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
(6)终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
7、窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;
8、检验和,占2字节,校验首部和数据这两部分;
9、紧急指针,占2字节,指出本报文段中的紧急数据的字节数;
10、选项,长度可变,定义一些其他的可选的参数。MSS最大报文长度,通过置位,协商能承载的TCP数据的大小。
https://blog.csdn.net/weixin_43997530/article/details/104651351 //这是前面单独写的一篇文章,这里不做过多叙述
滑动窗口机制
在进行三次握手时会通告对端,自己的窗口大小,而窗口大小决定了在收到确认前可以发送的字节数;如图所示,在第二步发送数据时,由于对端的窗口为3,所以可以在没有确认的情况下连续发送三个字节,当主机B处理一个报文后,此时缓冲区空出一个位置,当主机B回复ACK时,就将窗口大小置为1,表示我只能接收1个字节,如果多了可能会造成丢失,这时主机A就会仅发送一个字节数据。这样做可以大大提高传输的效率
停止等待协议
在因为某些因素如网络延迟,数据包丢失等等,没有收到数据包或者确认包时,在计时器超时后,会对数据包进行重传,这也是TCP可靠的一个因素之一。
慢启动、拥塞避免、快重传、快恢复
慢开始算法的思路就是,不要一开始就发送大量的数据,先从1慢慢增加,试探一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。
为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需设置一个慢开始的门限值ssthresh状态变量。ssthresh的用法如下:
当cwnd < ssthresh时,使用慢启动算法 ,即拥塞窗口数量呈指数增长。
当cwnd > ssthresh时,改用拥塞避免算法,即拥塞窗口大小为线性增长。
当cwnd = ssthresh时,慢开始与拥塞避免算法任意。
拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间就把发送发的拥塞窗口cwnd加K(K为常数),即线性增长,而不是指数增长。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢启动的门限设置为出现拥塞时的发送窗口大小的一半。然后使用快恢复算法,拥塞窗口以线性方式增长,直到网络出现拥塞时,拥塞窗口再次减半,重复以上操作。
UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。
因为UDP是无连接的。在传输数据之前,不需要进行复杂的三次握手来建立连接。在传输数据时,没有协议间通信流量(确认信号),也不需要浪费不必要的处理时间(接收确认信号再发一下)。传输结束后,也不用再用四次握手握手来结束连接。
|
TCP |
UDP |
可靠性 |
可靠 |
不可靠 |
建立连接 |
面向连接 |
无连接 |
报文 |
面向字节流 |
面向报文 |
传输方式 |
点对点 |
一对一,一对多,多对多 |
传输效率 |
低 |
高 |
流量控制 |
有(滑动窗口) |
无 |
拥塞控制 |
有 |
无 |
应用场景 |
对传输效率要求低,对传输准确性要求高,要求有连接的场景 |
对传输效率要求高,对准确性要求低 |
当网络硬件失效或者负担太重时,数据包可能就会产生丢失、重复、延时、乱序的现象。这些都会导致我们的通信不正常的时候。如果让应用程序来担负差错控制的工作,无疑将给程序员带来许多复杂的工作,于是,我们使用独立的通信协议来保证通信的可靠性是非常必要的。
TCP一般用于文件传输(FTP HTTP 对数据准确性要求高,速度可以相对慢),发送或接收邮件(POP IMAP SMTP 对数据准确性要求高,非紧急应用),远程登录(TELNET SSH 对数据准确性有一定要求,有连接的概念)等等
1.在高效可靠的网络环境中(不需要考虑网络不好导致的丢包、乱序、延时、重复等问题),因为UDP是无连接的服务,不用消耗不必要的网络资源(TCP中的协议间通信)和处理时间(预期确认需要的时间),从而效率要高的多。
2.在轻权通信中,当需要传输的数据量很小(可以装在一个IP数据包内)时。如果我们使用TCP协议,那么先建立连接,一共需要发送3个IP数据包,然后数据传输,1个IP数据包,产生一个确认信号的IP包,然后关闭连接,需要传输5个IP数据包。使用TCP协议IP包的利用率为1/10。而使用UDP,只需要发送一个IP数据包。哪怕丢包(服务不成功),也可重新申请服务(重传)。UDP很适合这种客户机向服务器传送简单服务请求的环境。此类应用层协议包括TFTP , SNMP , DNS ,DHCP等。
3.在对实时性要求很强的通信中:在诸如实时视频直播等对实时性要求很高的环境中,从而允许一定量的丢包的情况下(直播比赛,前面丢失的包,重传出来已经意义不大了),UDP更适合。(可以根据具体需要通过应用层协议提供可靠性,不用像TCP那么严格。)