什么是
TCP/IP协议
?
什么是HTTP
协议?
以及TCP / UDP
等等, 这一系列问题, 应该是每个程序开发者, 或多或少都了解的, 因为涉及东西比较多, 有时候一口气也较难系统的阐述出来, 下面我们来试着说说看看.
什么是tcp/ip
?
在说这个之前我们首先来认识一下OSI
, 这又是一个什么玩意儿呢?
OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,是ISO组织在1985年研究的网络互联模型。该体系结构标准定义了网络互联的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层),即OSI开放系统互连参考模型
关于各层的解释, 可以参考下图:
看到这, 可能还有人会说, 这到底是干嘛用的. 那这个就又要从头说起了, 我们的手机, 电话, 或者个人电脑, 本质上都是一个独立的模块, 那么如何实现 互相打电话
, 发送消息
, 发送文件
呢? 那就需要依靠上面这个东西了, OSI
是一个网络互联模型
或者说是一种规范
, 又可以说是一种约定
. 它规定了, 如果你要实现互相通信, 就必须基于这个模型
,
举个例子
, 两个人面对面交谈, 我们也规定了就是必须说普通话
, 那普通话可以也可以类比做OSI
, 假想, 如果每个人不说普通话, 一个说蒙古语
, 一个说苗家话
, 那这两个人交谈起来,可想而知, 谁也听不懂在说什么, 那OSI
其实也就是这么个意思.
也就是说 不管什么终端, 什么设备, 要能够实现互相通信必须得遵守这个规范, 但是和我们人说话不一样的地方在于, 电子设备, 涉及到网络知识, 以及不同终端之间的差异性, 所以这个OSI
才会有这么层次, 具体每一层, 做各自的事情, 来实现通信.
但是, 由于这个规范很全面
, 很严谨
,又或者说叫苛刻
, 就导致在实际生活中推行这套模型
, 不太容易实现.或者说实现起来比较繁琐,
一个例子
,说房子装修的时候, 设计师画的图纸很详细, 很优秀, 但是实际施工的时候, 发现有些地方不太容易做到, 那我们在施工的时候就会根据实际情况做一些小的改动, 来实现最终的需求.
上面的一个装修房子的例子,就能很友好的帮我们引出TCP/IP
, ISO制定的OSI参考模型的过于庞大、复杂招致了许多批评。与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用。
TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的
协议簇
。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
上面是百度百科的定义, 敲黑板: TCP/IP是一个协议簇, 不仅仅指的是TCP和IP两个协议
.
OSI先有模型,后有协议,先有标准,后进行实践;而TCP/IP则相反,先有协议和应用,再提出了模型,且是参照OSI模型
。看图:
从图上可以更容易的看出来, 两者之间的关系, TCP/IP
, 可以理解为参考OSI
而出现的一种稍微简化的通信协议.到这大家应该和笔者一样, 脑回路稍微清晰一点了. 那么我们开始步入正题.
为了下面更好的进行阐述, 我们进一步了解一下, 在tcp/ip
中数据是如何实现传输的.
数据一层一层封装
)数据一层一层解析
)声明:
本文重点阐述在TCP/IP协议中, 的传输层
和应用层
的相关知识, 关于下面的两层设计到网络部分内容, 暂不做阐述
通过上面的部分我们知道, 传输层中, 包含有TCP
以及UDP
, 两种协议.
TCP和UDP协议是TCP/IP协议的核心。 TCP 传输协议:TCP 协议是一TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据
可靠传输
,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;
而UDP则不为IP提供可靠性、流控或差错恢复功能。一般来说,TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济
的应用。
密密麻麻, 看不明白, 如果看不懂, 只要明白, TCP是面向连接的, 可靠的
, UDP是不可靠的
说他是面向连接的, 可靠的, 关键在于, 他的握手机制
, TCP协议存在连接时三次握手
, 断开时四次挥手
什么是三次握手?
一个例子
: 两个人聊天在么?
在的
好的, 在就可以了
这个过程可以大致理解为进行了三次握手
, 确保两个人都在线, 然后你们两个就可以开始畅快聊天了. 有人说这也太矫情了, 但是也正是因为矫情, 才确保了 连接是可靠的, 保证双方都在线
什么是四次挥手?
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。
一个例子
: 你去舅舅家拜年
时间不早了, 我该回去了
好, 那我送你出门
(与此同时, 舅舅在等你起身往门口走)路上慢点, 注意安全
知道了, 你快回去吧, 外面冷
(等舅舅关门, 舅舅如果迟迟不关门, 你见状有点尴尬, 扭头走了)通过上面两张图, 我们看到了图中有ACK, FIN, SYN
等等, 那这些又是什么东西.
Sequence Number
:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题;
Acknowledgment Number
:32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题;
Offset
:给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;
URG
:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;
ACK
:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;
PSH
:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;
RST
:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;
SY**N
:表示同步序号,用来建立连接**。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手;
FIN
: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
上面一部分内容就说明了, TCP
协议在发送数据之前, 以及数据发送完毕之后, 进行的一系列操作, 确保了 连接的可靠性.
UDP
是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址
,它在网络上以任何可能的路径传往目的地,因此能否
到达目的地,到达目的地的时间以及内容的正确性都是`不能被保证的。
相比TCP
他没有什么 三次握手, 四次挥手, 所以他就没有什么可靠性可言,
一个例子
发快递(北京—>上海)
北京到上海路通了, 并且没有其他障碍, 包裹可以送达
)路通不通, 不知道, 包裹能不能按时送到也不知道
)所以UDP在很大一定程度上存在丢包的可能性, 那这玩意有什么用?, 虽然他不可靠但是也是有应用场景的:
当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。比如,日常生活中,常见使用UDP协议的应用如下:QQ语音QQ视频TFTP。
TCP比UDP可靠
上面我们说完了 TCP, UDP
, 紧接着看一下socket
应用在使用 TCP 或 UDP 时,会用到
操作系统提供的类库
。这种类库一般被称为API
(Application Programming Interface,应用编程接口)。 使用 TCP 或 UDP 通讯时,优惠广泛使用到套接字(Socket)的 API。套接字原本是由 BSD UNIX 开发的,但是后被移植到了 Windows 的 Winsock 以及嵌入式操作系统中。 应用程序利用套接字,可以设置对端的 IP 地址,端口号,并实现数据的发送与接收。 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket。 建立网络通信连接至少要一对端口号(Socket)
。Socket
本质是编程接口(API
),对TCP/IP 的封装
,TCP/IP 也要提供可供程序员做网络开发所用的接口,这就是 Socket 编程接口.
看到这里我们明白了,其实Socket
是封装了TCP/UDP
, 是开放给程序开发者的一个手册或者类库, 通过给Socket来设定不同的参数, 来实现一个TCP
或者UDP
, 所以在程序开发中, 真正和程序员打交道的便是Socket这个东西
写给非开发者:
Socket 好比一个厨子, 告诉他炒一盘TCP
他就给你抄一盘TCP
.
写到这, 我们针对于
传输层
的相关知识, 就介绍完了, 也就是我们的底座已经打好了,
一句话总结一下传输层的主要工作是定义端口,实现端口到端口的通信,TCP协议可以保证数据传输的可靠性。
下面的篇幅, 我们开始进入应用层
, 在下面我们着重介绍, 在应用层中常用的,HTTP
,FTP
,WebSocket
等等应用层协议.
可以这么说, 当数据到了
传输层
的时候,数据已经实现了从一个主机上的应用程序传输到另一台主机的应用程序了,但此时传过来的数据是字节流
,不能很好的被程序识别,操作性差
,因此,应用层定义了各种各样的协议来规范数据格式
,常见的有http,ftp,smtp等,在请求Header
中,分别定义了请求数据格式Accept和响应数据格式Content-Type,有了这个规范以后,当对方接收到请求以后就知道该用什么格式
来解析,然后对请求进行处理,最后按照请求方要求的格式将数据返回,请求端接收到响应后,就按照规定的格式进行解读
所以应用层的主要工作就是定义数据格式并按照对应的格式解读数据。
一张图:
我们在一开始介绍TCP/IP
的时候有一张图和这个类似, 都是为了说明, 数据在每一层如何封装, 这一张图更明朗一点. 图中红色部分框便是应用层
他在封装数据的时候, 在Appl(Application)
首部规定了, 对应那种协议来封装数据, 接收端也按照头部规定的协议来进行数据解析. 完成数据的交互.
一个例子
: 当数据到了传输层的时候已经实现了 互相发送消息,好比你发送一串数字 1 3 5 7 9
给对方, 但是这串数据实际什么含义, 是不够明确的. 对方也就不知道你要做什么是. 那应用层
的头部, 加了一个说明求和, 那么接收方在接收到这个消息之后, 就按照头部的规定, 将1 3 5 7 9
求和, 这样就获取到了真实含义的数据.
这个例子足以说明, 在应用层做了什么事, 但是也只是简单的知道做了什么事, 下面我们会依次介绍, 在应用层具体的协议;
什么是HTTP?
首先明确一点: HTTP协议是建立在TCP协议上的
HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是一个应用层协议,由
请求
和响应
构成,是一个标准的客户端服务器模型,是Web联网的基础,也是手机联网常用的协议之一
HTTP连接最显著的特点是:客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接
”。
因为, HTTP是建立在TCP之上的, 所以说他也是一种面向连接且可靠的协议
. 一个HTTP
请求通常包含三部分请求行
, 请求体
, 请求头
请求行:由3部分组成,分别为:请求方法、URL以及协议版本,之间由空格分隔。 -
请求头部,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。 请求头部的最后会有一个空行,表示请求头部结束,接下来为请求正文。
请求体
我们一开始说了HTTP是一次请求一次响应
, 也就是说 当发送方发送出去一个请求之后, 也就是经过了下图的步骤,
接收方解析完成数据之后, 需要给发送者一个响应, 然后将连接关闭, 那么本次通信结束, 那么在请求的时候有请求头, 那么响应的时候对应有响应头
, 响应行
, 响应码
作用是相同的, 但是内容稍有不同.下图一次完整的响应.
其他部分和请求的时候类似, 唯一不同的是 在响应行
里面多了状态码
状态码:为3位数字,200-299的状态码表示成功,300-399的状态码指资源重定向,400-499的状态码指客户端请求出错,500-599的状态码指服务端出错(HTTP/1.1向协议中引入了信息性状态码,范围为100~199)
在请求以及响应的时候, 有一个协议版本, 我们关注一下,
不同版本之间的区别
这有又是一个什么东西?
RESTFUL是一种网络应用程序的设计风格和开发方式,基于
HTTP
,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源.
看完定义我们稍作解释, 首先我们看一下我们平时使用HTTP做什么事, 发送一次请求到后台, 查询数据, 或者发送一条数据给后台删除一条数据
等等. 优秀的先辈们又想了, 能不能再指定一种规范
或者约定
, 查询的时候就发送查询的请求. 删除的时候就明确删除请求, 好比吃中餐就用筷子
, 吃西餐就用刀具
, 这样又能简化一些, 于是RestFul
又诞生了.
客户端使用GET、POST、PUT、DELETE个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
第二条中, 说明了, 在发起请求的客户端
的请求行
注明请求的方法, 那服务端接收到这个请求之后便可以直截了当知道, 要做什么操作. restful风格约定的方法, 不仅仅有get post put delete还有options等等方法, 大家可以去细致研究一下.
注意: 在使restful风格中, 使用delete方法, 并且客户端收到服务端的响应的时候, 并不代表真正删除了数据, 只能说明, 服务端收到了要删除的指令
我们关于HTTP协议就介绍完了, 一句话总结
基于TCP协议, 面向连接, 请求--响应
模式
HTTPS协议 = HTTP协议 + SSL/TLS协议
,在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。
SSL的全称是Secure Sockets Layer,即安全套接层协议,是为网络通信提供安全及数据完整性的一种安全协议。SSL协议在1994年被Netscape发明,后来各个浏览器均支持SSL,其最新的版本是3.0。
TLS的全称是Transport Layer Security,即安全传输层协议。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。
虽然TLS与SSL3.0在加密算法上不同,但是在我们理解HTTPS的过程中,我们可以把SSL和TLS看做是同一个协议。
验证
:
有时候, 我们在请求一些第三方的HTTPS服务的时候, 因为他的证书是自己生成的, 导致我们的请求会被拒绝, 所以有一个偷懒的办法就是, 在编写客户端的时候, 对于服务端的任何证书都添加信任, 也就是不管什么证书都认为是合理的, 可以规避没有证书的问题
说起WebService
, 我们再来认识一个新概念SOAP
SOAP(Simple Object Accrss Protocol,简单对象访问协议)是一种简单的基于XML的协议,可以使应用程序在分散或分布式的环境中通过HTTP来交换信息。
SOAP基于XML语言和XSD标准,其定义了一套编码规则,编码规则定义如何将数据表示为消息,以及怎样通过HTTP协议来传输SOAP消息,由四部分组成:
(1) SOAP信封(Envelope):定义了一个框架,框架描述了消息中的内容是什么,包括消息的内容、发送者、接收者、处理者以及如何处理消息。
(2)SOAP编码规则:定义了一种系列化机制,用于交换应用程序所定义的数据类型的实例。
(3) SOAP RPC表示:定义了用于表示远程过程调用和应答协定。
(4)SOAP绑定:定义了一种使用底层传输协议来完成在节点间交换SOAP信封的约定。
SOAP消息基本上是从发送端到接收端的单向传输,常常结合起来执行类似于请求/应答的模式。不需要把SOAP消息绑定到特定的协议,SOAP可以运行在任何其他传输协议
(HTTP、SMTP、FTP等)上。另外,SOAP提供了标准的RPC方法来调用Web Service以请求/响应模式运行。
SOAP是Web Service的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,可以支持不同的底层接口
,像HTTP(S)或者SMTP。
在网上找到一篇针对于SOAP的专项文章
, 有需要的小伙伴可以去看一下.点击访问
下面在认识一下网络服务描述语言(Web Services Description Language,WSDL)
是一种基于可扩展标记语言(XML)的语言,它用来描述业务提供的服务,并为个人和其他企业提供一种以电子形式获得这些服务的方法。网络服务描述语言是由微软、IBM和Ariba所倡议的统一描述、发现和集成(UDDI)的基石。UDDI是一种基于XML的世界业务注册表,这样企业就可以在互联网上列出自己的企业名称和服务。网络服务描述语言(WSDL)就是这样用的。
UDDI 是一个独立于平台的框架,用于通过使用 Internet 来描述服务,发现企业,并对企业服务进行集成。
UDDI 指的是通用描述、发现与集成服务
UDDI 是一种用于存储有关 web services 的信息的目录。
UDDI 是一种由 WSDL 描述的 web services 界面的目录。
UDDI 经由 SOAP 进行通信
UDDI 被构建入了微软的 .NET 平台
上面说的三个小知识介绍完了, 那么我们的Webservice其实也介绍完了
, 因为Webservice的三要素便是 SOAP, WSDL, UDDI
一句话总结
SOAP用来描述传递信息的格式, WSDL 用来描述如何访问具体的接口, UDDI用来管理,分发,查询webService 。
这又是一个什么东西?
我们在上面说到了HTTP是一种单向请求, 一次响应的协议
, 也就是只能由客户端发起请求, 服务端收到请求, 返回对应的响应.
一个例子
就如现在BS架构的系统, 页面作为客户端, 请求后台的数据, 页面展示的是某一些警报信息
(在这里简单补充一点业务知识, 所谓的警报告警类似于一个监控, 当后台数据库中有了某些系统的告警的时候, 页面要实时展示出来. 提醒人们说哪里哪里告警了)
上面的例子当我们使用HTTP
协议的时候, 就需要客户端间隔一段时间, 就去发起请求到后台查询, 如果有数据了, 就展示, 如果没有就等待下一次的数据查询, 那这样就造成了很多资源以及带宽的浪费. 为什么这样呢?
主要是因为HTTP单次请求,服务端不能主动将数据发送给客户端导致的
, 这里可能有杠精出来了, 说那你用HTTP长轮询
, 保持一个长连接, 这样不就可以了么?
解释一下, HTTP长轮询
是省去了连接的过程, 也就是我们在HTTP部分说的, 每次连接需要三次握手
这个过程是比较耗时的. 那么长连接
便是, 数据交换完了之后, 连接不断, 复用一开始的连接, 这样就免去了每次连接 进行握手的时候, 请求头的交换. 这样确实能省去一些资源的消耗, 但是延时问题怎么保证呢? 依旧是客户端去轮询, 客户端不知道服务端什么时候有数据了.
一个例子
客户端请求完一次, 没有获取到数据, 与此同时, 服务端立马有了一条数据. 那么客户端只有在下一次轮询间隔
到来的时候才能获取到数据, 这一过程就产生了延时.
好了, 背景介绍完了, 我们开始进入Websocket
WebSocket是一种网络通信协议,RFC6455中定义了WebSocket的通信标准。WebSocket是HTML5提供的一种在单个TCP连接上进行全双工通讯的协议。
作为下一代的Web标准,HTML5中的WebSocket又被称为“Web的TCP”。WebSocket的出现使得浏览器提供对Socket的支持成为可能,从而在浏览器和服务器之间提供了一个基于TCP连接的双向通道
。HTML5定义的WebSocket协议能更好地节省服务器资源和带宽
,并能实时地进行双向通讯
。浏览器通过JavaScript向服务器发出建立WebSocket连接的请求,当连接建立后,客户端和服务器可以通过TCP连接直接交换数据
。
简单来说,WebSocket是HTML5提供的一种在单个TCP连接上进行全双工通讯的协议。WebSocket使客户端和服务器之间的数据交互变得更加简单,允许服务器主动向客户端推送数据
。使用WebSocket浏览器和服务器只需要完成一次握手就直接可以创建持久化的连接,并进行双向数据传输
。
那么我们上面的问题就 迎刃而解了, 只要后台一有数据, 立马可以主动推送数据到页面. 是不是很优秀呢.
Socket协议
Socket协议?
为什么这么说呢, 因为经常听到别人这样说.
首先明确一点: 敲黑板 Socket 并不属于应用层, 并且它不属于协议, 他只是传输层TCP/UDP
的一个封装, 开放出来的一个API , 供开发人员来调用的.
我们应用层的协议底层都是通过调用Socket
来实现的. 如果这个Socket是TCP的, 我们也可成这个连接是一个TCP连接反之便是UDP
.
那么问题来了? 为什么要说是 Socket协议
呢?
这么说, 也不能明确的说不对, 只不过太囵囤了, 我们经常说的Socket其实是属于一种在应用层实现的一种自定义协议, 并且也是有TCP 以及 UDP两种
类似什么 FTP, HTTP, SMTP等等一样, 只不过是你自己实现的一种协议.
因为我们也说了, 其实数据到了传输层
就已经能够传递了, 应用层做的无非就是数据的合理解析
所有有些时候会发现, 自定义的协议比较繁琐, 主要是因为需要自己写代码按照定义的规则,编码去解析字节码
例如什么Little-endian, Big-endian, Middle-endian
等等一系列规则, 这些规则也可以自定义.
虽然是自定义实现的, 但是依旧是有Server
和Client
两者, 有人说为什么要自己造?
这个东西繁琐是繁琐, 不过是很香的. 因为通用的一些协议, 编码什么的大家都墨守约定规范, 导致黑客入侵的时候就比较容易, 因为每个环节做什么 这些东西都是公开的, 但是自定义的协议, 在入侵的时候就费点劲了, 但也不是坚不可摧的哦.
在本篇文章中, 我们重点介绍了TCP/IP协议簇
的相关知识, 关于应用层一些SMTP, TELNET
等等协议我们也没有过多介绍到, 以后有时间再做补充, 此外在本文都是侧重理论知识, 关于每种协议的客户端, 服务端的Java实现
, 笔者都有, 如果有需要参考的可以密我.
如果文中有观点错误的地方, 望大家及时指出来, 共勉共进!!
最后,武汉加油!!, 中国加油!!