Android程序员的自我修养-计算机网络篇(一)

Android程序员的自我修养-计算机网络篇(一)_第1张图片
程序员的自我修养

计算机网络学习的核心内容就是网络协议的学习。
网络协议是为计算机网络中进行数据交换而建立的规则、标准或者说是约定的集合。
本文对Android程序员需要了解的部分计算机网络知识,进行简单梳理。


Android程序员的自我修养-计算机网络篇(一)_第2张图片
OSI参考模型

TCP和UDP

TCP和UDP使用IP协议从一个网络传送数据包到另一个网络。
把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。
TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。TCP和UDP是FTP,HTTP和SMTP之类使用的传输层协议。

虽然TCP和UDP都是用来传输其他协议的,它们却有一个显著的不同:TCP提供有保证的数据传输,而UDP不提供。这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点,而UDP不提供任何这样的保证。

TCP :
     Transmission Controller Protocol是传输控制协议
     提供的是面向连接、可靠的字节流服务。
UDP :
    User Data Protocol是用户数据协议
    是一个简单的面向数据包的运输层协议。

TCP和UDP的区别和优缺点

区别1 是否连接

TCP:连接
客户端和服务器交换数据之前,需要在双方之前建立一个TCP连接之后才能传输数据。
一个TCP连接需要经过三次对话才能建立起来,这三次对话的目的是使数据包的发送和接收同步。
UDP:不连接

区别2 是否可靠

TCP:可靠
建立了连接,TCP提供数据超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据从一端传到另一端。
UDP:不可靠
未建立连接,只是把应用程序传给IP层的数据包发送出去,也不能保证是否能到达目的地,且没有超时重发等机制。

区别3 应用场合

TCP:传输大量数据,对可靠性较高要求,如moba游戏中的游戏大厅、商城
UDP:传输少量数据,可靠性不高的要求,如moba游戏中的战斗

总结

TCP:传输控制协议,客户端和服务器传输数据前要建立连接,此连接需要经过三次对话建立,
由于建立了连接,提供数据超时重发,丢弃重复数据等数据,因此适合传输大量数据,但传输速度比较慢。

UDP:用户数据协议,不必建立连接,客户端和服务器之间直接将IP层的数据包发送出去,
不能保证数据是否成功到达目的地,也没有超时重发等机制,但传输速度很快,适合小数据,可靠要求不高的数据传输。

TCP的三次握手和四次挥手

TCP是基于IP的虚电路可靠的全双工通信服务,基本上可以分为链接建立,数据传输,链接拆除三个阶段。
在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.
其中,对于我们日常的分析有用的就是前面的五个字段。
它们的含义是:

SYN表示建立连接||FIN表示关闭连接||ACK表示响应||PSH表示有 DATA数据传输||RST表示连接重置
TCP建立连接需要进行的三次握手
Android程序员的自我修养-计算机网络篇(一)_第3张图片
三次握手GIF
  • 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。
  • 第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
  • 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
为什么是三次握手?

谢希仁的《计算机网络》中关于该问额的解释:

主要是为了防止已失效的连接请求报文段突然又传到了B,因而产生错误。假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络结 点长时间滞留了,一直延迟到连接释放以后的某个时间才到达B,本来这是一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误认为是A又发出一次 新的连接请求,于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了,这样一直等待A发来数据,B的许多 资源就这样白白浪费了。

Google论坛中对该问题的讨论:

这个问题的本质是, 通过一个不完全可靠的信道, 最少需要几次消息传输, 信道两边的人能够对一个问题达成一致. 对于TCP来说, 无论有没有初始
序号的要求, 想要两边都同意开始传出数据, 就至少需要3次消息的交换:
0次: 显然不行
1次: A->B, A不知道B是否同意
2次: A->B, B->A. B不知道A是否收到自己的消息, 因为信道不完全可靠
3次: A->B, B->A, A->B. 两边都收到了对方的ACK, 意味着各自都了解了对方的意图, 从而可以对是否开始通信这个最简单的问题达成一致.

从逻辑上讲,三次握手是[最省]的建立TCP链路[两个通道]规程机制了,所以就应该三次握手。

TCP拆除连接需要进行的四次挥手
Android程序员的自我修养-计算机网络篇(一)_第4张图片
四次挥手GIF

由于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状态,完成四次挥手。

上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是2个MSL,2个MSL后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。
它的作用是重传最后一个ack报文,确保对方可以收到。因为如果对方没有收到ack的话,会重传fin报文,处于time_wait状态的套接字会立即向对方重发ack报文。

2个MSL就是4分钟。MSL就是maximium segment lifetime——最长报文寿命。这个时间是由官方RFC协议规定的。


Socket和WebSocket

Socket

计算机网络中的Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

Socket 接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,用以开发TCP/IP网络上的应用程序。

WebSocket

WebSocket和Socket的关系就像Java和Javascript,基本上没有太大关系,但有不能说完全没有关系。

WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket的出现是用来弥补HTTP协议在持久通信能力上的不足,它的握手是以HTTP的形式发起的,通过第一个request建立连接,之后交换的数据都不需要发送HTTP header就能交换数据。

可以把WebSocket想象成HTTP,HTTP和Socket什么关系,WebSocket和Socket就是什么关系。


更新一张神图 TCP在三种状态下的数据传输过程


Android程序员的自我修养-计算机网络篇(一)_第5张图片
TCP

推荐文章:

https://www.jianshu.com/p/43a25804b2e8 TCP和UDP协议
https://blog.csdn.net/Tong_jy/article/details/78477634 学习TCP和UDP的总结
https://groups.google.com/forum/#!topic/pongba/kF6O7-MFxM0/discussion Google论坛关于TCP建立为什么是三次握手的讨论
https://zhuanlan.zhihu.com/p/40667482 【TCP】详解TCP 三次握手和四次挥手

你可能感兴趣的:(Android程序员的自我修养-计算机网络篇(一))