盛唐年间,天下安定,由于疆域太大传递信件不易,就有民间的能人异士向皇帝谏言,每个州县都建立信息司来养信鸽。由信鸽来传递信件。皇帝觉得可行遍开始施行。
        一日皇帝命小吏从东都洛阳发一封信件到西京,这个小吏第一次去信息司发信件,到了信息司发现只有一个人处理信件。小吏便把信件交给了信息司的小哥,只见小哥娴熟的拿出只信鸽告诉它去西京,就放飞了,然后将信件誊抄了一份,将信件撕成了三份,并标上了序号。过了不一会小哥刚刚放走信鸽飞回来了,只见小哥又将信鸽放飞了。然后拿出三个信鸽分别将三份信件绑到信鸽的腿上,然后将信鸽放飞了。这时候小吏就问了小哥一句:”为什么刚刚只把信鸽放飞而不放信件啊!“。这时小哥不耐烦地说:”我要试试,我们州县附近有没有猎人,看看信鸽能不能飞出去。如果飞不出去就要找县衙派兵沿途检查一下路线了。“;小吏又问:”既然我们已经看到信鸽飞回来了,为什么还要再次放出去。“。小哥继续说:”西京那边还不知道他能不能发信鸽。我需要告诉他一声。“,谈话间只看到传递 1,3 号信件的鸽子飞回来了。小哥说:”又有一只鸽子飞丢了。“,小吏急忙问道:”怎么办!如果出了差错,我可是要被杀头的。“。小哥说:”莫着急我们再等一柱香的时间,如果还不回来我们在把 2 号信件重新发一次就好了。“。一炷香过后,小哥又拿出一只信鸽把 2 号信件绑到鸽子的腿上。不一会传递 2 号信件的信鸽飞回来了。只见小哥又娴熟的拿出一只信鸽放了出去,不一会飞回两只,然后小哥又放出去一只信鸽。小吏不解的问小哥:”你这个在干什么!“。小哥说:“我这是再告诉西京那边我的信息发完了。然后西京告诉我他知道了并让我把备份的信件销毁。我再告诉西京没问题”。终于皇帝的信件发完了。
        小吏回去后感觉比较有意思,东都西京中间隔着两个州,信鸽是怎么如何飞的呢?他又专程去问了信息司的小哥。小哥说:”我也不知道信鸽会飞到那个州,如果信鸽飞到其他州,其他州的人会看到信鸽的目的地是西京,他会改变信鸽的飞行方向,直到信鸽飞到西京才算结束。“。

以上的小故事就是个简单 TCP 传输。
小吏便算是应用层,皇帝让他去发消息。
信息司的小哥身兼传输层和网络层。
信鸽便是链路层。

 

TCP/IP 分层网络

1. 应用层

应用层决定了向用户提供应用服务时通信的活动。
TCP/IP 协议族内预存了各类通用的应用服务。例如:HTTP、SSH、FTP 等。

2. 传输层

应用层的下一层就是传输层,提供处于网络连接中的两台计算机之间的数据传输
常见的传输层协议有 TCP、UDP 等。

3. 网络层

网络层又称网络互连层。
网络层用来处理在网络上流动的数据包,数据包是网络传输的最小数据单位。该层规定了通过怎样的路径到达对方的计算机,并把数据包传送给对方。
网络层的作用就是在众多选项内选择一条合适的传输路径。

4. 链路层

链路层又称数据链路层,网络接口层
用来处理连接网络的硬件部分,控制操作系统、硬件的设备驱动。
我们能够看到的交换机、网线、光纤等也属于物理层

TCP 是什么

TCP 的全称是传输控制协议(Transmission Control Protocol)位于传输层,它是一种有连接的协议,提供可靠的字节流服务[注1]。而可靠的传输服务是指,能够将数据准确可靠的传递给对方。数据为何能准确无误的送达目标处,就是因为 TCP 协议采用了三次握手策略,当然除了三次握手,TCP 协议还有其他手段来保证通信的可靠性

TCP 三次握手

①发送端首先发送一个带 SYN 标志的数据包给对方

 

②接收端收到标有 SYN 的数据包后回传一个带有 SYN/ACK 标志的数据包表示确认信息

 

③发送端在发送一个带有 ACK 标志的数据包给接收端表示握手成功

Android开发需要了解的TCP/UDP网络协议_UDP

 更通俗的以对象举例:

 

Android开发需要了解的TCP/UDP网络协议_安卓_02

 

如果握手成功后连接断开,再次连接还需要重新握手

TCP 四次挥手

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

第一次挥手:
Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:
Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:
Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:
Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

Android开发需要了解的TCP/UDP网络协议_TCP_03

Android开发需要了解的TCP/UDP网络协议_安卓_04

 

UDP 是什么

UDP 的全称是用户数据报协议(User Datagram Protocol)同样位于传输层,它是一种无连接的协议,提供面向事务的简单不可靠信息传送服

TCP 与 UDP 的差异

  1. TCP 是有连接的而 UDP 是无连接的
  2. TCP 是可靠的连接而 UDP 是不可靠的
  3. UDP 不需要各种可靠性策略所以相比 TCP 性能要高不少
  4. 因为 UDP 的连接步骤少,报头内容少所以相比 TCP 更加的省流量
  5. TCP 只能一对一连接传递消息而 UDP 可以一对一、一对多、多对一和多对多

抓包软件 Wireshark

注1:字节流服务是指,为了方便传输,将大块数据分割成报文段为单位的数据包进行管理的服务

【TCP相关疑问】

   最后整理几个常见的TCP相关的疑问:

  • Q1 为什么在TCP协议里,建立连接是三次握手,而关闭连接却是四次握手呢?
  • A1 因为当处于LISTEN 状态的服务器端SOCKET当收到SYN报文(客户端希望新建一个TCP连接)后,它可以把ACK(应答作用)和SYN(同步作用)放在同一个报文里来发送给客户端。但在关闭TCP连接时,当收到对方的FIN报文时,对方仅仅表示对方没有数据发送给你了,但未必你的所有数据都已经全部发送给了对方,所以你大可不必马上关闭SOCKET(发送一个FIN报文),等你发送完剩余的数据给对方之后,再发送FIN报文给对方来表示你同意现在关闭连接了,所以通常情况下,这里的ACK报文和FIN报文都是分开发送的。
  • Q2为什么TIME_WAIT 状态还需要等2*MSL秒之后才能返回到CLOSED 状态呢?
  • A2因为虽然双方都同意关闭连接了,而且握手的4个报文也都发送完毕,按理可以直接回到CLOSED 状态(就好比从SYN_SENT 状态到ESTABLISH 状态那样),但是我们必须假想网络是不可靠的,你无法保证你最后发送的ACK报文一定会被对方收到,就是说对方处于LAST_ACK 状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT 状态的作用就是用来重发可能丢失的ACK报文。
  • Q3关闭TCP连接一定需要4次挥手吗?
  • A3不一定,4次挥手关闭TCP连接是最安全的做法。但在有些时候,我们不喜欢TIME_WAIT 状态(如当MSL数值设置过大导致服务器端有太多TIME_WAIT状态的TCP连接,减少这些条目数可以更快地关闭连接,为新连接释放更多资源),这时我们可以通过设置SOCKET变量的SO_LINGER标志来避免SOCKET在close()之后进入TIME_WAIT状态,这时将通过发送RST强制终止TCP连接(取代正常的TCP四次握手的终止方式)。但这并不是一个很好的主意,TIME_WAIT 对于我们来说往往是有利的。