T C P / I P协议族分为四层:链路层、网络层、运输层和应用层,每一层各有不同的责任。在T C P / I P中,网络层和运输层之间的区别是最为关键的:网络层( I P)提供点到点的服务,而运输层(T C P和U D P)提供端到端的服务。

一个互联网是网络的网络。构造互联网的共同基石是路由器,它们在 I P层把网络连在一起。第一个字母大写的 I n t e r n e t是指分布在世界各地的大型互联网,其中包括 1万多个网络和超过1 0 0万台主机。

在一个互联网上,每个接口都用 I P地址来标识,尽管用户习惯使用主机名而不是 I P地址。域名系统为主机名和 I P地址之间提供动态的映射。端口号用来标识互相通信的应用程序。服务器使用知名端口号,而客户使用临时设定的端口号。

 

1.TCP建立连接

标志 字符缩写 描述
S SYN 同步序号
F FIN 发送方完成数据发送
R RST 复位连接
P PSH 尽可能快地将数据送往接收进程
. 以上四个比特均置0

对TCP首部中部分标志比特的字符表示

三次握手:

1) 请求端(通常称为客户)发送一个 S Y N段指明客户打算连接的服务器的端口,以及初始序号(I S N,在这个例子中为1 4 1 5 5 3 1 5 2 1)。这个S Y N段为报文段1。

2) 服务器发回包含服务器的初始序号的 S Y N报文段(报文段2)作为应答。同时,将确认序号设置为客户的I S N加1以对客户的S Y N报文段进行确认。一个 S Y N将占用一个序号。

3) 客户必须将确认序号设置为服务器的 I S N加1以对服务器的 S Y N报文段进行确认(报文段3)。

 

发送第一个S Y N的一端将执行主动打开。接收这个S Y N并发回下一个 S Y N的另一端执行被动打开。当一端为建立连接而发送它的 S Y N时,它为连接选择一个初始序号。 I S N随时间而变化,因此每个连接都将具有不同的 I S N。

建立一个连接需要三次握手,而终止一个连接要经过 4次握手。这由 T C P的半关闭造成的。既然一个 T C P连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个 F I N来终止这个方向连接。当一端收到一个 F I N,它必须通知应用层另一端几经终止了那个方向的数据传送。发送F I N通常是应用层进行关闭的结果。收到一个F I N只意味着在这一方向上没有数据流动。一个 T C P连接在收到一个 F I N后仍能发送数据。

 

四次挥手:

报文段4发起终止连接,它由 Te l n e t客户端关闭连接时发出。这在我们键入 q u i t命令后发生。它将导致 T C P客户端发送一个F I N,用来关闭从客户到服务器的数据传送。

当服务器收到这个 F I N,它发回一个A C K,确认序号为收到的序号加 1(报文段5)。和S Y N一样,一个F I N将占用一个序号。同时 T C P服务器还向应用程序(即丢弃服务器)传送一个文件结束符。接着这个服务器程序就关闭它的连接,导致它的 T C P端发送一个F I N(报文段6),客户必须发回一个确认,并将确认序号设置为收到序号加1(报文段7)。

 

 

2.为什么服务器不将对客户 F I N的A C K与自己的 F I N合并,从而将报文段数减少为3个?

首先,服务器对客户的 F I N的确认一般不会被延迟,而是在F I N到达后立即发送。应用进程需要一些时间来接收 E O F,告诉它的T C P关闭它这一端的连接。

第二,服务器收到客户的 F I N后,并不一定要关闭它这一端的连接,仍然可以发送数据。

 

 

3.为什么要有第三次握手?

防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。(比如:造成连接建立而server端一直等待,浪费资源)

 

 

4.TCP重传机制

TCP要保证所有的数据包都可以到达,所以,必需要有重传机制。

注意,接收端给发送端的Ack确认只会确认最后一个连续的包,比如,发送端发了Sequence 100,200,300,400,500一共五份数据(假设size都是100),接收端收到了Sequence 100,200,于是回ack 300(300 = SeqNum + Size),然后收到了Sequence 400(注意此时300没收到),此时的TCP会怎么办?我们要知道,SeqNum和Ack是以字节数为单位,所以ack的时候,不能跳着确认,只能确认最大的连续收到的包,不然,发送端就以为之前的都收到了。

 

超时重传机制

每次发送数据包时,发送的数据报都有seq号,接收端收到数据后,会回复ack进行确认,表示某一seq号数据已经收到。发送方在发送了某个seq包后,等待一段时间,如果没有收到对应的ack回复,就会认为报文丢失,会重传这个数据包。

针对上面的情况,接收端不回ack,死等300,当发送方发现收不到300的ack超时后,会重传300。一旦接收方收到300后,会ack回500(500 = Sequence 400 + Size 100)——意味着300和400都收到了。但是,这种方式会有比较严重的问题,那就是因为要死等300,所以会导致400和500即便已经收到了,而发送方也完全不知道发生了什么事,因为没有收到Ack,所以,发送方可能会悲观地认为也丢了,所以有可能也会导致400和500的重传。

 

快速重传机制

接收数据一方发现有数据包丢掉了。就会发送ack报文告诉发送端重传丢失的报文。如果发送端连续收到标号相同的ack包,则会触发客户端的快速重传。比较超时重传和快速重传,可以发现超时重传是发送端在傻等超时,然后触发重传;而快速重传则是接收端主动告诉发送端数据没收到,然后触发发送端重传。

比如:如果发送方发出了1,2,3,4,5份数据,第一份先到送了,于是就ack回2,结果2因为某些原因没收到,3到达了,于是还是ack回2,后面的4和5都到了,但是还是ack回2,因为2还是没有收到,于是发送端收到了三个ack=2的确认,知道了2还没有到,于是就马上重转2。然后,接收端收到了2,此时因为3,4,5都收到了,于是ack回6。

 

 

 

 

 

 

 

 

科普:

因特网的传输层有两个协议UDP和TCP:

UDP(User Datagram Protocol)只提供无连接的不可靠的服务,应用进程通过<远端IP地址,远端端口号>向远端进程发送数据,应用进程并不要求远端进程进行确认。

TCP(Transmission Control Protocol)为应用程序之间提供面向连接的可靠的字节流服务。TCP为全双工协议,提供流控制机制,即允许接收方控制发送方的发送速度,此外还提供拥塞控制功能。

 

 

推荐阅读:

https://github.com/xuelangZF/CS_Offer/blob/master/Network/TCP.md