TCP传输协议

1、TCP中一些名词解释

(1)MSS(maximum segment size)

TCP的最大报文段大小,在TCP报文段中有一个16位的部分用于放置该值,因此最大为65535,可以利用setsockopt() 和getsockopt设置和获取TCP_MAXSEG来影响MSS;

(2)MSL(maximum segment lifetime)

IP报文段能在网络中存在的最长时间,这个是系统级的参数,没有接口修改,windows上可以通过注册表修改,通常为2分钟,最低为30秒,linux上面没法修改;

(3)TTL(time to live)

是由源主机设置的生存时间,不是具体的时间值,是只ip数据报在网络中能够经历的最大跳数,即能够经过的最大路由数,这个字段的设置在IP的首部,由8位组成,因此最大的跳数是255;可以通过setsockopt设置;

(4)RTT(round trip time)

指客户端到服务端往返所花时间,tcp含有动态估算rtt的功能,同时RTT也是受到网络拥塞情况的变化而变化;

(5)MTU(maximum transmission unit)

最大传输单元,这个是由硬件规定,不同网络MTU是不一样的;

2、TCP报文头中标志位含义

(1)URG

紧急标志位,当这个标志置1时,TCP报文中的16位紧急指针就有效,这个紧急指针就是指紧急数据的偏移量,一共这么多字节;

(2)ACK

确认序号有效,表示收到指定序号的TCP报文;

(3)PSH

指示接收方应该尽快将这个报文段交给应用层,这个PSH标志位跟socket中的no_delay方法相关联,就是设置发送不延迟,发送方不管发送内容有多小,都直接发送,接收方接收到这个数据后不等待,直接将数据交由应用程序处理;这个就是关闭TCP中数据发送的Nagle算法(Nagle算法是指在TCP连接上最多只能有一个未被确认的未完成小分组,在该分组的确认到达之前不发送其他小分组,而是将这些小分组缓存起来等确认到达时以一个大分组的形式发出去,这样可以有效避免过多的小分组出现在网络中导致数据传送效率低,网络拥塞);

(4)SYN

TCP建立连接的标志;

(5)FIN

发送端完成发送任务,TCP关闭连接的标志;

(6)RST

重置连接,这个标志位通常用来表示连接的异常断开,RST标志位表示TCP连接出现硬错误;

3、TCP连接的状态

LISTEN:监听连接请求

SYN_SENT:在发送连接请求后(发送SYN),等待匹配的连接请求

SYN_RECEIVED:在收到连接请求并发送连接连接请求的确认ack之后(接收到SYN,并发送SYN+ACK)

ESTABLISHED:收到了SYN+ACK,并发送了ACK之后,或者收到建立连接的ACK之后,连接建立起来了

FIN_WAIT_1:应用进程先主动关闭,发送了FIN之后;

FIN_WAIT_2:在发送FIN之后,收到对方的FIN+ACK之后;

CLOSING:说明是同时关闭连接,发送FIN之后,又收到了对方的FIN,因此也会回复FIN+ACK,之后进入此状态

TIME_WAIT:收到对方的FIN,并发送了FIN的ACK之后,或者在同时关闭连接中,收到对方对自己发的FIN的ACK回复之后进入此状态,表示处于即将关闭双方的连接的状态,这个阶段需要等待2MSL时间,因为最后一个确认FIN的ACK可能丢失或者未到达对方,对方会重复发送一次FIN,这个FIN又会在MSL时间内到达,因此需要等待一个往返的最大时间,如果这期间没有收到新的FIN,说明最后一个ACK已经到达,如果收到,说明最后一个ACK丢失了,需要重新发送FIN的ACK,并再次等待2MSL时间;

CLOSE_WAIT:应用进程还没有发送FIN,但是收到了对方的FIN之后,发送FIN的ACK然后进入此状态;

LAST_ACK:应用进程在发送了对方FIN的ACK之后,自己又发送了FIN之后,就进入此状态,在此状态等待FIN的ACK到达;

CLOSED:在2ML时间到达之后,或者收到最后一个FIN的ACK之后进入此状态;

TCP连接的建立正常情况下需要三次握手,断开正常情况下需要四次挥手;这些状态在编程中都是不能看到的,都是TCP自己维护,API没法获取到;以上各个状态的变迁图如下:

4、TCP传输协议

(1)重传(从发送方角度考虑)

TCP连接是可靠的数据传输连接,其可靠性的一个重要保障就是能够重传在网络中丢失的报文,因此TCP重传就很重要了,而TCP重传又分为超时重传和快速重传两种,超时重传是指发送方自己在发送数据之后,在超时重传值(RTO)时间到达时还没收到ACK,则触发超时重传;快速重传是指接收方发现接收到的报文不是自己想要的报文,中间有漏掉的报文序列时,就会连续发送三个相同的ACK(请求丢失序列的报文)给发送方,发送方在收到连续三个相同的报文ACK的时候就会触发快速重传机制,发送丢失的报文;快速重传是对超时重传的一个补充,使得重传更加及时;

a)超时重传

超时重传的时间RTO(retransmission timeout),是根据若干次的RTT计算平均而来(有一个较复杂的计算算法),会根据网络环境的变化而动态调整;每次发送数据后到达RTO时间,如果ACK还没到达,就会进行超时重传,如果重传之后还没收到ack,下次重传的RTO值就会翻倍(乘以2),知道重传到达系统设置的重传次数,然后就会关闭连接;默认情况下,Windows主机默认重传5次。大多数Linux系统默认最大15次。两种操作系统都可配置。

b)快速重传

发送方一旦收到三个重复的ACK时,就会触发快速重传,这时,所有待发送的报文都会放在队列中等待,直到快速重传发送完为止;

(2)流量控制(从接收方角度考虑)

TCP发送数据时,发送方会考虑接收方能够接受处理多少数据,不能随意发送数据包大小,否则会导致网络拥塞,TCP使用滑动窗口来进行流量控制;在TCP报文段中一个16位的窗口字段,用来保存当前自己可以接收数据的缓冲区大小,接收方可以通过根据接收缓冲区大小设置窗口的大小,从而控制发送的发送速度;

发送方的发送窗口包括已发送但是没有收到ACK的报文以及等待发送的报文;而接收窗口指接收缓冲区空余的大小;当然这里每次发送的数据报大小是MSS控制的,在TCP连接建立之初的三次握手中会包含通信双方各自的MSS大小,从而发送的时候直接发送最大报文段大小(MSS)的报文,如果过程中接收方的接收窗口小于MSS,则发送方会以实际窗口大小来发送报文段;

滑动窗口协议包括以下几种:

a)停止等待协议

发送方需要在上一次发送的数据报的ACK到达之后才能发送新的数据,这会导致信道利用率降低;

b)后退N协议

发送方可以连续发送N个数据报,每次发送一个报文都会设置超时计时器,如果某个报文触发了超时重传,则发送方需要重传该报文之后的所有报文,接受方也必须丢弃该报文之后的所有报文;因此这样会导致很大的浪费;在网络环境不好的情况下会导致效率更低;

c)选择重传协议

选择重传协议是对后退N协议的改进,也就是说在发送方依然可以连续发送N个报文,只是在其中某个报文触发超时重传或者快速重传之后,发送方只发送丢失的那个报文段,接受方也不会丢弃之前接收的报文,会将出错报文之后的报文存放在缓冲区,等收到丢失报文之后在一起交给应用层;这样有效避免了浪费,不过对接收缓冲区有一定的要求,通常滑动窗口采用此协议;

d)零窗口

某些情况下,接收方可能来不及处理接收到的数据包,无法再接收新的数据,这时就可以使用零窗口协议,将接收窗口大小设置为0,发送方就不会再发新的数据;等到接受方有足够的缓冲空间了,又会发ACK消息给发送方来打开窗口,但是这个ACK可能丢失,从而导致发送方和接受方进入相互等待死循环;为了避免这种情况,发送方会设置坚持定时器,每隔一段时间就会向接受方发送一个探查报文,看接受窗口是否打开,坚持定时器的时间是指数退避的(每次坚持时间乘以2),最多每隔60秒发送一次,知道窗口打开或者应用程序连接关闭;

e)糊涂窗口综合征

指的是滑动窗口出现接收窗口较小(小于一个报文段大小即MSS)的情况下发送数据包,不是报文段满长的情况下发送数据,这种情况下带宽利用率很低;要避免这种情况,可以在发送方和接收方两边着手;

接收方不通告小窗口:当接受窗口为0后,除非能够接收一个最大报文MSS大小或者缓冲区的一半大小,否则不通告窗口打开

发送方不发送小包:使用TCP的Nagle算法,或者在没有等待被确认的报文时,直接发送数据;或者发送方累积到一个满长度的报文段(MSS),或者是报文大小大于接收窗口一半的时候在发送;

(3)拥塞控制(从网络角度考虑)

TCP重传以及滑动窗口的流量控制都只是从发送方和接受方的角度来考虑,还没有从网络环境的角度来考虑,如果网络出现拥塞了,各种重传只会导致拥塞更加严重,因此TCP有针对网络拥塞的控制策略,包括有:慢启动、拥塞避免、拥塞发生和快速恢复;

a)慢启动,指数增长

TCP支持慢启动算法,此算法通过控制发送端发送新的数据报进入网络的速率应该跟接收端返回确认的数据报的速率相同,从而起作用;慢启动为发送方增加了一个拥塞窗口(congestion window,cwnd),这是发送方用于控制流量的方法,而接收方的通告窗口大小是接收方控制流量的方法;发送方每次取拥塞窗口和通告窗口的最小值作为发送数据报总数的上限;每次发送方会以大小为MSS的数据报为单位,将允许发送数量的数据报全都发出去;

在TCP连接建立之初,cwnd初始化为一个MSS报文段大小,当每接收到一个ACK时,拥塞窗口就会增加一个MSS报文段大小,因此cwnd会呈指数增长(因为随着cwnd增大,允许发送的报文数量增加了,每个报文收到ACK都会增加一个MSS,因此是翻倍),如下图;

慢启动是指最初的启动发送上限小,但是增长其实并不慢;当然不能一直这样增长下去,发送方还有一个参数是慢启动阈值(ssthresh,通常是65535),当cwnd的大小达到ssthresh时,慢启动结束,进入拥塞避免阶段,如下;

b)拥塞避免,线性增长

在这个阶段,在每收到一个ACK,为cwnd增加(1/cwnd)* MSS大小,所以一个完整的轮回后,即全部发送的数据报的ACK都收到后,cwnd一共只增加了一个MSS大小((1/cwnd)*MSS*cwnd=MSS),因此cwnd的增长从指数增长变为线性增长,避免增长过快导致网络拥塞;

c)拥塞发生,乘法减小

当出现数据包丢失的情况,说明网络中出现拥塞了,这个时候设置ssthresh为当前窗口(实际发送上限:cwnd和接受方通告窗口的较小值)的一半,同时根据不同情况处理:

如果是超时重传:说明拥塞比较严重,进入慢启动阶段,将cwnd设置为1个MSS报文段大小,重传丢失的数据,当有一个新的数据报被确认后,cwnd就可以增长一个MSS大小;

如果是快速重传:说明可能发生了轻度拥塞,但还不需要进入慢启动阶段,进入快速恢复阶段(跟快速重传对应处理,类似于拥塞避免阶段);

d)快速恢复

重传丢失的报文段,并将cwnd设置为ssthresh+3*MSS报文段大小(因为有3个重复ACK,因此有三个老的报文离开网络被接受了),每次收到另一个重复的ACK时,cwnd增加一个MSS报文段大小并发送一个报文(进行重传),当收到新的数据包的ACK时,说明之前丢失的数据包都已经被确认了,恢复到拥塞避免阶段,设置cwnd为ssthresh的大小;

(4)保活机制

TCP提供保活心跳控制机制,默认情况下是2小时内通信双方没有任何通信,TCP保活机制就会激活,每隔75秒发送一次探查报文,一共发送10次,如果这10次都没有相应,则判定连接已经关闭,断开连接;

5、TCP服务器设计

呼入连接请求队列,当服务器正在相应其它事件时,这时有新的连接请求出现,TCP默认会先完成三次握手,接受连接,然后将该连接放入一个连接请求队列,等待应用层接受连接进行处理,这个队列的长度可以设置,python中是socket.listen(backlog),这个backlog就是连接队列的长度,叫积压值,如果这个队列满了,这新进来的连接不会再收到响应,如果队列中的连接长时间没有被应用层处理,也会因为超时而断开;

时间: 2024-10-26 21:07:52

TCP传输协议的相关文章

TCP传输协议使用

TCP传输协议,也称之为套接字连接,比较安全,三次握手!,必须确保对方计算机存在,才能连接,而且是长时间连接. 缺点是传输速度有点慢. 你用 socket 去连接 ServiceSocaket 服务器端,ServiceSocaket 会创建一个,Sockets 然后你的Socket ,连接服务器端创建的Socket 最后你的Socket 和 服务器端的 Socket 都会创建一个 OutputStrea 和InputStream 流用来传输数据. 如下图: ServerSocket : 服务端,

TCP传输协议中如何解决丢包问题

TCP在不可靠的网络上实现可靠的传输,必然会有丢包.TCP是一个"流"协议,一个详细的包将会被TCP拆分为好几个包上传,也是将会把小的封裝成大的上传,这就是说TCP粘包和拆包难题. 但是许多人有不同的理解.TCP协议本身确保传输的数据不会丢失完整性.如果在传输过程中发现数据丢失或数据包丢失,最大的可能性是在发送或接收程序的过程中出现问题. 例如,服务器向客户端发送大量数据,并且发送频率非常高,因此发送链接中很可能会出现错误(1.程序处理逻辑错误:2.多线程同步问题:3.缓冲区溢出等)如

TCP传输协议如何进行流量控制?

TCP流量控制,简单来说就是让数据传输端传输的速率不要太快,让数据接收端来得及接收,利用滑动窗口机制可以很方便的在TCP连接上实现对数据传输端的流量控制.TCP的窗口单位是字节,不是报文段,数据传输端的发送窗口不能超过接收端给出的接收窗口的数值,流量控制的机制是控制丢包率,主要目的:让数据传输端了解数据接收端当前的接收能力,可灵活调整传输速率.流量控制机制图如下图所示: 滑动窗口: TCP采用大小可变的滑动窗口进行流量控制,窗口大小的单位是字节. 数据传输窗口在连接建立时由双方商定.但在通信的过

java中TCP传输协议

class TcpClient { public static void main(String[] args) throws Exception { //创建客户端的socket服务,指定目的主机和端口 Socket s = new Socket("192.168.1.10",10003); //为了发送数据,获取socket流中的输出流 java.io.OutputStream out = s.getOutputStream(); out.write("hello tcp

Rsyslog的三种传输协议简要介绍

rsyslog的三种传输协议 rsyslog 可以理解为多线程增强版的syslog. rsyslog提供了三种远程传输协议,分别是: 1. UDP 传输协议 基于传统UDP协议进行远程日志传输,也是传统syslog使用的传输协议: 可靠性比较低,但性能损耗最少, 在网络情况比较差, 或者接收服务器压力比较高情况下,可能存在丢日志情况. 在对日志完整性要求不是很高,在可靠的局域网环境下可以使用. 2.TCP 传输协议 基于传统TCP协议明文传输,需要回传进行确认,可靠性比较高: 但在接收服务器宕机

TCP/IP协议与HTTP协议区别SOCKET接口详解

网络由下往上分为:      物理层--                       数据链路层-- 网络层--                       IP协议 传输层--                       TCP协议 会话层-- 表示层和应用层--           HTTP协议   socket则是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据 如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据.关于TCP/

学习笔记之TCP/IP协议的传输方式

一.通过网络发送数据,大致可以分为面向有连接与面向无连接两种类型: 1.面向无连接型包括以太网. IP.UDP等协议. 2. 面向有连接 型包括ATM.帧中继.TCP等 协议. 通过一张图了解一下: 面向有连接型 面向有连接型中,在发送数据之前,需要在收发主机之间连接一条通信线路 面向有连接型就好比人们平常打电话,输入完对方电话号码拨出之后,只有 对端拿起电话才能真正通话,通话结束后将电话机扣上就如同切断电源.因此在 面向有连接的方式下,必须在通信传输前后,专门进行建立和断开连接的处理.如果与对

传输层TCP/UDP协议

可靠的TCP协议(传输层) 1)  TCP封包结构如下图: 各字段的含义为: 封包序号:记录每个封包的序号,当TCP封包大于IP封包的长度时,TCP封包就需要拆分成更小的包,来下发给网络层,通过该字段可以让接收端重新将TCP数据组合起来. 回应序号:回传给客户端的响应码,当客户端收到这个确认码时,就能够确定之前传递的封包已经被正确的收下了. 资料补偿:由于Options字段是任意的,为了确认整个封包的大小,就用这个字段来说明整个封包区段的起始位置. 保留:保留字段,还未被使用. 控制标志码:用来

对TCP/IP协议的一些看法(7):传输层

这几天由于实验室断网,所以一直不能发随笔,但是好习惯还是要坚持. 今天讲一下一个重要的层——传输层.传输层的协议主要分为TCP协议和UDP协议.前者称为传输控制协议,后者为数据包传输协议.今天主要讲一下传输层的概述,之后会对TCP协议和UDP协议进行详细介绍. 我们知道,数据包如果在IP层传输,其传输的可靠性不能保证,这就会造成重要数据的丢弃.这显然是不被允许的.因此只能依靠传输层的TCP协议来保证数据传输的可靠性,这也正是TCP的一个主要特征,即能够保证数据完整到达接收方.为什么这么说呢?因为