接收封包的顺序与发送封包的顺序相同。
接收方最多只收一份数据,不会重复接收。
支持任意大小的数据传送
支持发送端与接收方同步
允许接收方给发送方发送flow control的指令
支持每个host主机上运行多个applicaiton,多个process
IP是不可靠的端对端协议,容易丢包,数据包乱序,重复发送数据包,将数据包限定到特定的大小(MTU),发送数据有任意长的延时。
基于不可靠的IP协议之上的不可靠服务,UDP:端到端的,基于process-to-process的服务。
TCP的传送是Application对Application,传送的Application传什么内容,接收的Application就可以很可靠的收到传送的内容。
TCP能够克服IP层可有的(容易丢包,数据包乱序,重复发送数据包,将数据包限定到特定的大小(MTU),发送数据有任意长的延时。)等问题。
TCP在使用时,需要先建立连线,connection oriented,而UDP不需要预先建立连线。
TCP的传输特性:Byte-steam service,传输以Byte为单位。一次丢n个Byte,n为正整数。发送与接收Byte的数量相同,顺序相同。发送与接收的量可以不同。比如发送300Byte的数据,可以分三次发送,每次100Byte,接收可以分三次接收,每次收100Byte,也可以分6次接收,每次接收50Byte. 分三次送,分六次取。只需要保证顺序对,总量正确即可。
跟资料在网络上到底分为几个封包发送无关。分几次送,几次取无关。只需要保证数据总量一致,顺序相同。
Receiver:具有传送节奏主导权,可以避免sender发送快掉,让接收端的buffer无法应对,丢包的场合。
Congestion control:尽管TCP已经与对方建立连线,但是如果丢的太快,不仅仅是receiver无法处理,整个网络也受不了。如果大家全部把封包都丢尽internet,就有可能会导致网络阻塞。Congestion control的目的:大家在丢封包给网络是,不要让网络发生阻塞。避免太多的封包进入网络,引起网络阻塞。
不能送太快,不能让receiver处理不过来。Flow Control发生在发送端与接收端之间,有接收端控制,实现起来比较简单。
不能送太多,让整个网络瘫痪/阻塞。Congestion control实现起来比较麻烦,因为网络中没有人告诉你现在网络上是否有拥塞。 TCP在处理congestion control的一个挑战是,它如何知道整个网络发生了拥塞。router不会告诉发送端。如果真的网络发生阻塞,router也不会告诉sender,sender会一直不停的向网络中发送数据。如果网络拥塞时,发送端可能会无法收到ACK,封包掉,说明网络可能发生了拥塞。如果封包掉的多,说明网络的拥塞情况比较严重,则会控制发送的速度减慢,让网络的拥塞状况有所缓解。
Congestion control:如何侦测网络已经发生了拥塞;当发生拥塞时,如何应对处理。
TCP:沟通的对象是网络的最边缘,End to End,一般运行在server/nb/手机等终端设备上。TCP的连线需要跨越整个internet,与之前的point-to-point link不同。
Datalink layer:如何让直接建立连线的link上面做传输
TCP:如何让sliding window算法应用到TCP?
TCP的传输based on IP,位于第4层。跨越整个internet,与point-to-point link不同。
TCP需要建立一个logical connection,在实际网络上并没有真正的保留一条固定的实体链路。透过internet,每个封包走的路径可能不同,因为实际链路不固定,可能一条,可能多条。
TCP建立的连线,可能有不同的RTT时间。round trip time:一个来回的时间。
同样的server,比如说建立了100个对外的TCP link,这些不同的TCP link的RTT时间可能差异很大。
TCP需要一个机制,得到接收方到底有多大的buffer/resource来处理封包。TCP care的是发送的量的大小,不care这些data分几次/拆分成几个封包发送。flow control机制:需要让sender知道,接收端到底能提供多少resource
congestion control:TCP需要一个机制来知道网络的容量是多大。 TCP只知道自己与哪个router链接在一起。具体网络中有多少router,怎么链接,是不知道的。网络的容量随时变化,如果网络拥塞,则容量较少,如果空闲,则容量较大。TCP需要知道现有网络的容量是多大,才有办法控制自己的发送速率。
TCP不会每个byte逐个在网络上传送。它会搜集许多data,buffer起来,足够大之后,才生成一个封包,一起发送,来提高网络利用率。如果每个byte单独发送,则header开销会很大。
接收端,同样也是将接收到的封包先buffer起来,当攒够足够大的量时,才通知application来取走这些data。
TCP在网络上传送的资料的单位:叫做segments.
TCP如何处理byte stream?
TCP首先将byte存在send buffer中,当足够大时,则生成一个segment,在网络上传送。
接收端,也是先将data存在receive buffer中,当攒够足够量时,通知application来接收。
application 发出去的时候,是byte stream
接收端applicaiton接收的时候,也是byte stream。
每次byte发送的多少不care,care的是byte的总量一致,byte的顺序一致。中间如何送/分几次送,接收如何收/分几次收不care。
source port:source IP对应的那台电脑对应的哪个applicaiton (从哪个电脑送:source IP记录在IP header中;从哪个电脑接收,目的IP也存在IP header中)。
Destination port:目的IP对应的那台电脑对应的哪个application。 每台电脑上不同的application,通过port number来区分。
Sequence Number: 可靠传输,基于sliding window协议。 sequence number必须落在接收视窗内才可以被接收。 TCP是一个byte stream,TCP的sequence number必须细致到每一个byte都有一个不同的sequence number。
TCP不care data被切割成多少个封包传送,care的是第一个byte对应的sequence number是什么,即care数据中每个byte的顺序。
Sequence number:是指这个封包所携带的data的第一个封包所对应的sequence number。 每一个byte都有一个sequence number--byte orientated。
Ack number:告诉对方我收到的情况。这个number之前的所有data已经成功收到,cumulative ack, 这个number以后的data我还在等待。
TCP中,Seqence number与Ack number的长度都是32bit
header中有6个flag。
SYN:建立连线,该为为1,表示要建立连线。连线建完,发送data结束后,就要取消连线。
FIN:该位设为1,表示接收端通知发送端要拆掉连线,close连线。
ACK:该为位1,表示该封包带的ACK number是一个有意义的值。如果该位为0,表示上面ACK number对应的栏位没有特别的意义,不必理会。
RST:连线建立以后,就开始发送data。只要有一方(发送或接收)发现网络传输有异常,比如发现监听,黑客等,就会马上将该位置1,reset,重来,强制将连线清除。
PSH:push,将buffer里面的内容,无论多少,强制打包,发送出去。不会等到原来设定的临界值,提前强制打包发送。接收端在收到PSH设为1的封包后,同样无论buffer里面有多少data,都会强制将data发给applicaiton,用于接收。基于应用,如果是传档案,可能会接收慢慢传输。如果是视频,则需要对方马上看到内容,会将psh设为1
URG:设为1,表示该data里面有些特别的资讯。
Urgent Pointer:用于在URG flag设为1时,指示特别资讯在data中的位置。urgent pointer所指示位置的前面,位该紧急资讯。 urgent pointer所指示位置的后面,是传输的普通data。
Advertised window:用于做flow control。共16bit,6万多byte。 receiver告诉sender,最多可以发送64K(65536)的量的data。sender发送完65536的data后,就等receiver的ack。 是receiver控制sender发送的量。
Advertised Windows:自己的接收窗口有多大,你最多能发送多少量的data
RESET:强制断线。
PUSH:强制清空buffer
pseudoheader:除了TCP header,连同IP header里面的内容一起检查。
建立连线时,要告诉对方自己的buffer,同时要带自己的sequence number。
通常连线的发起者位client,server等待别人的连线请求。server等待别人建立连线时,也要准备好welcom accept socket。
第一步:SYN=1,建立连线。同时将自己的sequence number告诉对方。
第二步:Server将SYN+ACK bit设置为1,同时带一个sequence number y
Acknowledgement = x+1,server等的data sequence number必须从x+1开始
第三步:client也回送一个收到的信息,ACK flag设置为1,将Acknowledge nuber设置为y+1。 从server过来的sequence number是y,因而client回给server的acknowledgement是说,client现在的状态是在等待从server发过来的sequence number从y+1开始的data。
data里面的sequence number:是data里面第一个byte的sequence number
假设client请求连线中断。client会送一个封包出来,将FIN flag设置为1.
Server收到后,会回应一个ACK,表示我已经收到这个flag。然后server回给client一个FIN
Client收到以后,也会给Server回一个ACK,表示自己已经收到从Server发过来的FIN。Client通常会在等30秒之后,才会正式关闭链接。因为,封包丢掉internet中,可能存在delay,在连线正式关闭之前,能够收到此刻还在internet上面传送的封包,确保数据的完整性。
Client要建立连线时,首先要送SYN,接着进入SYN_SENT state。
接着接收SYN/ACK,回ACK,当完成后,就进入ESTABLISHED state。
Client 发起关闭的链接,会送FIN这个封包,发送完后,进入FIN_WAIT_1 state,
发送完后,就会收到从Server发过来的ACK,接着进入FIN_WAIT_2 state,
如果Client再收到一个从Server发国来的FIN,就会给Server回一个ACK,同时进入TIME_WAIT状态,等待30秒后,进入close状态。 此处送ACK,目的是让Server收到响应,让Server进入CLOSE状态。
Server为了让client可以建立连线,需要打开连线,将port打开,建立listen socket,让别人可以连进来。 建立好之后,进入LISTEN state。
接着接收SYN,发送SYN/ACK,当完成后,就进入SYN_RCVD state。表示已经接收到对方的SYN。
如果收到对方的ACK,就进入ESTABLISHED state。
Server如果收到FIN,就要给Client回一个ACK,代表它收到的Client端的中断链接请求,进入CLOSE——WAIT state。
接着送一个FIN出去,等待Last ACK,当等到后,进入close状态。
SampleRTT:通过测量每个Segmanet/ACK pair得到的最新的RTT的值。
EstRTT:基于之前的data得到的RTT的值。
当有重新发送时,很难判断收到的ACK是基于第一次传送的ACK还是第二次传送。
a>如果计算的SampleRTT是基于第一次发送的segment时间,与收到重送的ACK之间的时间区间,则计算得出的SampleRTT时间这大于实际的RTT时间,计算不准确。
b>如果计算的SampleRTT是基于第二次重新传送的时间与收到第一次传送的ACK的时间区间,则得出的SampleRTT时间明显小于实际的RTT时间,计算不准确。
不去采样RTT时间。
每次重新发送时均将timeout水煎加倍
Karn-Partridge算法还是无法消除整个网络的congestion。如果time时间太短,则整个网络中会因为不必要的过多重传而加重负担。
Karn/Partridge算法的主要问问题:无法将采样SampleRTTs时间的变异进行考虑。
正对小的SampleRTT变异的场合,说明传输比较稳定,测得的EstimatedRTT具有更高的可信度,没必要将timeout时间乘以2加入考虑。
当SampleRTTs之间的变异比较大的场合,说明传输不稳定,timeout值此时不可与EstimatedRTT有过紧密的耦合。因为此时SampleRTT不稳定。
Jacobson/Karels算法考虑最新采样得到的SampleRTT与之前的EstimatedRTT之间的变异因素。
左边:发送的Seq=70,表示从序列号为70的Byte开始发送,长度为20byte,则正常发送接收时,应该收到接收端返回的ACK=90,表示序号为90以前的Byte都已经收到,正在等待序号为90的data。当ACK丢失,则Timeout之后重传。
右边:连续发送两个segment,第一个Seq=70/20bytes,第二个Seq=90/10bytes。在第一个segment time之时,应该收到的第一个ACK没收到,于是重送第一个segment。在第一个Segment重送的timeout到期之前,收到了第一次发送的第一个segment与第二个segment的ACK,于是针对第一个segment重送的数据包,接收端会回送ACK=100,表示100之前的数据包都已经收到,正在等待发送第100个数据包。
每次发送都会收到接收端回应的ACK,即便该ACK已经被收到。
因此,当一个数据包发送乱序时,TCP就可能会重发它最后发送的数据包对应的ACK。
这个针对爹二次发送的相同的ACK称为duplicate ACK
当发送端收到重复的ACK,则他知道接收端一定发生了乱序,表明先发送的数据包可能丢失。同样有可能表明(理解为),先发送的数据包只是被delay,没有丢失,发送端一直等到收到一定数量的重复的ACK之后,才会判定之前发送的数据包已经丢失,于是启动该数据包的重传机制。TCP在收到3个重复的ACK之后,就会判断数据包已经丢失,启动丢失重传机制。
Sender发送1/2/3/4/5,其中数据包2丢失。
接收端在收到3/4/5时,回的ACK需要都为2,表示2以前的都已经成功收到,正在等待2
当收到重传的2时,接收端会回复ACK=6,表示6以前的都已经成功收到,正在等6
TCP想知道整个网络的容量有多大,从而知道自己可以送多少封包到网络。
congestion Window: 发送能力
Advertised Window:由接收端控制,发给sender,告诉它自己的接收能力。
最大的窗口:CongestionWindow与AdvertisedWindow的最小值。
AIMD:如果发现网络顺畅,每个RTT时间结束,将Congestion Window的大小加1. 1个MSS。
改进方式:不必等到一个RTT时间结束才扩到CongestionWindow,而是在每收到一个ACK,就扩大一点点,每次扩大的幅度为MSS/CongestionWindow。
如过目前的CW=5,则每收到一个ACK,就扩大1/5MSS,同样满足一个RTT时间增加一个MSS的条件
如过目前的CW=8,则每收到一个ACK,就扩大1/8MSS,同样满足一个RTT时间增加一个MSS的条件,但是增加的传输能力
AIMD:线性增加,每个RTT增加一个MSS。当增加到极限时,会将窗口减半,然后再次线性增加,如此轮环往复,看起来就是一个锯齿状的曲线。
SLOW Start:为了改善AIMD加速慢的不足,每个SIMD让窗口加倍,快速达到上限。
TCP基于ACK控制节奏。
每收到一个ACK,就将发送窗口加1.
透过每收到一个ACK,增加一个MSS,达到每个RTT,发送窗口加倍的目的。
当到达上限时,连续收到三个duplicate ACK,就会将窗口减半,然后以AIMD的方式,线性逐步毕竟极限。
但是,当遇到timeout状况时,发送窗口会直接将为1(1个MSS),然后以SlowStart的方式,指数方式尽快到达threhold(发生timeout时窗口的一半),当到达threhold后,再以AIMD的方式逐步毕竟极限。
上图:两个灰色区间,为SlowStart区间,以指数方式尽快到达Threhold。
当收到3-duplicate ACK后,发送窗口马上减半,然后以AIMD的方式缓慢逼近性能极限,次过程为Congestion-Avoidance phase。
当发生Time-out时,会马上将窗口将为1,然后以SlowStart的方式,马上到达Threhold(发生timeout之前的CongestionWindow的一半),然后以AIMD的方式逐步毕竟新的上限。
Throughput = W/RTT
Transport layer:process-to-process transmission。
每个process由IP + Port Number组成。
每个不同的process,都对应不同的port number
TCP:基于不可靠的IP层的网络的基础上提供可靠的服务,资料量不变,顺序正确。 怎么做?3-way hand-shaking,引入senquence number(每一个byte都有一个sequence number),连线的建立与拆除都是一个state machine
Time out时间:之前是RTTx2. 新的设计算法,能够让timeout时间更加与实际网络状况相符。
TCP:透过ACK重送,cummulative ACK
Byte-stream protocol
Fast retransmission:3-duplicate ACK.一样的ACK重复三次就认为该封包已经lost,提早重送。
TCP congestion control:AIMD
Timeout:通常认为网络阻塞更严重,将congestion window降为1