网络协议

こ雲淡風輕ζ 提交于 2020-03-09 11:01:08

网络协议介绍
OSI(Open System Interconnect)七层模型:通信的特点是对等通信
从上往下分别为
应用层:为应用程序提供服务,此层应有的网络协议有HTTPS,HTTP,FTP等协议
实际公司A的老板就是我们所述的用户,而他要发送的商业报价单,就是应用层提供的一种网络服务,当然,老板也可以选择其他服务,比如说,发一份商业合同,发一份询价单,等等。

表示层:数据格式化,数据加密;表示层提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别
由于公司A和公司B是不同国家的公司,他们之间的商定统一用英语作为交流的语言,所以此时表示层(公司的文秘),就是将应用层的传递信息转翻译成英语。同时为了防止别的公司看到,公司A的人也会对这份报价单做一些加密的处理。这就是表示的作用,将应用层的数据转换翻译等。

会话层:建立,管理,维护会话,会话层就是负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
会话层的同事拿到表示层的同事转换后资料,(会话层的同事类似公司的外联部),会话层的同事那里可能会掌握本公司与其他好多公司的联系方式,这里公司就是实际传递过程中的实体。他们要管理本公司与外界好多公司的联系会话。当接收到表示层的数据后,会话层将会建立并记录本次会话,他首先要找到公司B的地址信息,然后将整份资料放进信封,并写上地址和联系方式。准备将资料寄出。等到确定公司B接收到此份报价单后,此次会话就算结束了,外联部的同事就会终止此次会话。

传输层:建立,管理和维护到端的连接;传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。
传输层就相当于公司中的负责快递邮件收发的人,公司自己的投递员,他们负责将上一层的要寄出的资料投递到快递公司或邮局

网络层:IP地址及路由的选择
网络层就相当于快递公司庞大的快递网络,全国不同的集散中心,比如说,从深圳发往北京的顺丰快递(陆运为例啊,空运好像直接就飞到北京了),首先要到顺丰的深圳集散中心,从深圳集散中心再送到武汉集散中心,从武汉集散中心再寄到北京顺义集散中心。这个每个集散中心,就相当于网络中的一个IP节点。

数据链路层:提供介质访问和链路管理;将比特组合成字节,再将字节组合成帧,使用链路层地址 (以太网使用MAC地址)来访问介质,并进行差错检测。

物理层:物理层;传输的介质:集线器,中继器,网线,双绞线,同轴电缆,实际上最终信号的传输时通过物理层实现的,通过物理介质传输比特流。
快递寄送过程中的交通工具,就相当于我们的物理层,例如汽车,火车,飞机,船。

TCP/IP五层模型
从上往下分别为:
应用层
传输层:四层交换机,四层的路由器
网络层:路由器,三层交换机
数据链路层:网桥,以太网交换机,网卡
物理层:中继器,集线器,双绞线

TCP协议的通讯流程
一、HTTP是什么

    http(HyperText Transfer Protocol),超文本传输协议,是互联网上应用最广泛的一种网络协议,所有www文件都必须遵守的一个标准,是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。说白了,就是大家都约好互相之间按照一种固定的规则来进行通讯。

    http也可以说成是一种客户端和应答服务器端请求和应答的标准(TCP)。通过使用浏览器或其他工具(如google的Postman),客户端发起一个到应答服务器上指定端口(如Tomcat的8080或jmx的1099等)的http请求,或者反过来,服务器给客户端发送一个回应。在客户端和应答服务器端可能存在多个中间层,比如代理、网关或者隧道。

二、HTTP请求报文

    http请求报文是指客户端到服务器端的消息,客户端通过发送http请求向服务器请求对资源的访问。包括三个部分:请求行、请求头部、请求数据。请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。

   1.请求行:包含请求方法、uri和协议的版本,用空格分隔,例如:GET/sample.jsp HTTP/1.1

    2.请求头部:包含有关客户端环境及请求正文的信息,如请求正文长度、浏览器所用编码格式等,例如;

Accept:image/gif.image/jpeg./

Accept-Language:zh-cn

Connection:Keep-Alive

Host:localhost

User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)

Accept-Encoding:gzip,deflate

    3.请求数据:即客户端发送给服务器的内容,可为空(GET请求就没有请求数据),例如:username=jinqiao&password=1234

PS:1.请求头部和请求数据之间必须有空行,用以区分。

     2.最常用的请求头部是Content-Type(请求编码方式)和Content-Length(请求数据长度),例如:

Content-Type: application/x-www-form-urlencoded

Content-Length: 35

三、HTTP应答报文

    http应答报文是指服务器回应http请求,发送给客户端的消息。也包括三个部分:状态行、响应头部、响应数据。

1 状态行:协议版本、状态码、简要描述,例如:HTTP/1.1 200 OK

2 响应头部:必须指明Content-Type,其他可选,例如:Content-Type: text/plain

3 响应数据:即服务器回应客户端的内容。

PS:常见状态码

1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。

四、HTTP请求与响应步骤

    http请求和响应,说白了就是计算机之间的问答对话。http请求是提问者,http响应是回答者。详细步骤如下图所示。

    

1 建立连接

    先解析DNS,把localhost变成ip(127.0.0.1),然后根据127.0.0.1和端口号8080(没有端口号则使用默认的端口)建立socket。也可以理解为通过“三次握手”建立TCP连接,确定通讯正常。

2 发送请求命令

    socket建立好之后,客户端开始向web服务器发送请求命令(GET/POST等)。

3 发送请求头(和请求正文如果有)

   客户端先发送与自身相关的信息,再发送空行表示请求头发送完毕,如果是post则继续发送请求正文。

4 回传状态行

    应答第一步,发送协议版本和状态码(200、503、404等)

5 回传应答头

    应答第二步,先发送自身相关信息、Content-Type(必须)及被请求的文档,在发送空行宝石应答头发送完毕。

6 回传应答正文

    应答第三步,根据应答头的Content-Type指定的格式发送应答正文。

7 关闭连接

   一次‘会话’完成,如果设置了Connection:keep-alive则TCP连接不关闭,否则关闭连接。

五、TCP/IP协议

TCP/IP协议模型(Transmission Control Protocol/Internet Protocol),包含了一系列构成互联网基础的网络协议,是Internet的核心协议,通过20多年的发展已日渐成熟,并被广泛应用于局域网和广域网中,目前已成为事实上的国际标准。TCP/IP协议簇是一组不同层次上的多个协议的组合,通常被认为是一个四层协议系统,与OSI的七层模型相对应。

HTTP协议就是基于TCP/IP协议模型来传输信息的。

1 链路层
也称作数据链路层或网络接口层(在第一个图中为网络接口层和硬件层),通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。ARP(地址解析协议)和RARP(逆地址解析协议)是某些网络接口(如以太网和令牌环网)使用的特殊协议,用来转换IP层和网络接口层使用的地址。

2 网络层
也称作互联网层(在第一个图中为网际层),处理分组在网络中的活动,例如分组的选路。在TCP/IP协议族中,网络层协议包括IP协议(网际协议),ICMP协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。
IP是一种网络层协议,提供的是一种不可靠的服务,它只是尽可能快地把分组从源结点送到目的结点,但是并不提供任何可靠性保证。同时被TCP和UDP使用。TCP和UDP的每组数据都通过端系统和每个中间路由器中的IP层在互联网中进行传输。
ICMP是IP协议的附属协议。IP层用它来与其他主机或路由器交换错误报文和其他重要信息。IGMP是Internet组管理协议。它用来把一个UDP数据报多播到多个主机。

3 传输层
主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。
TCP为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。为了提供可靠的服务,TCP采用了超时重传、发送和接收端到端的确认分组等机制。
UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。一个数据报是指从发送方传输到接收方的一个信息单元(例如,发送方指定的一定字节数的信息)。UDP协议任何必需的可靠性必须由应用层来提供。

4 应用层
应用层决定了向用户提供应用服务时通信的活动。TCP/IP 协议族内预存了各类通用的应用服务。包括 HTTP,FTP(File Transfer Protocol,文件传输协议),DNS(Domain Name System,域名系统)服务。

     当应用程序用TCP传送数据时,数据被送入协议栈中,然后逐个通过每一层直到被当作一串比特流送入网络。其中每一层对收到的数据都要增加一些首部信息(有时还要增加尾部信息),

六、TCP三次握手

第一次握手

    建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;

第二次握手

    服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

第三次握手

   客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

为什么要三次握手

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

具体例子:“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”

七、四次挥手

第一次分手

   主机1(可以使客户端,也可以是服务器端),设置Sequence Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;

第二次分手

   主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;

第三次分手

   主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;

第四次分手

   主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。

为什么要四次分手
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
以上过程,基于TCP/IP 协议的套接字的工作流程,如下图所示:

5、问题
(1)为什么要三次握手而不是两次?
答:这主要是为了防止已失效的的连接请求报文段。
假设,客户端发出连接请求报文段,但是该连接请求报文段 在某个网络节点中长时间滞留,导致客户端因为超时又发送第二个连接请求报文段 。第二个连接请求与服务器建立连接,而第一个连接请求报文段 以至于延误到连接释放以后才到达服务器。本来这个连接早已经失效了,如果只采用两次握手的话,服务器会误认为客户端又发送了一次连接请求,从而统一建立连接。所以,采用三次握手可以很好的避免这个问题。

(2)为什么连接的时候是三次握手,断开的时候是四次挥手?
答:因为连接的时候,服务器收到客户端的SYN连接报文后可以直接发送SYN+ACK报文(其中SYN报文是用来同步的,ACK报文是用来应答的);但是,断开的时候,服务器收到客户端的FIN报文后并不会立即关闭SOCKET,而是先回复一个ACK报文,告诉客户端“我收到你发的FIN报文了”,直到服务器的所有报文都发送完了,才发送FIN报文,因此不会一起发送FIN+ACK。故需要四步握手。

(3)为什么有时候是三次挥手?
答:因为假设在服务器发送ack给客户端的时候,服务器端已经没有要发送的数据,则这时服务器会将ACK捎带在第二次挥手的FIN报文里面返回回去,也就是第二和第三合在一起发送了。

(4)为什么TIME_WAIT的时间是2MSL?
答:因为MSL是TCP报文的最大生存时间,因此TIME_WAIT持续存在2MSL的话就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失,否则服务器立刻重启,可能会收到来自上一个迟到的数据而引起错误。同时,也是在理论上保证最后一个报文可靠到达。假设最后一个ACK丢失,那么服务器会重发一个FIN。这时,虽然客户端的进程不在了,但是TCP连接还在,仍然可以重发LAST_ACK。

(5)服务器关闭之后为什么不能立即重启?
答:这是由于套接字处于TIME_WAIT状态引起的,这个状态会持续2MSL时间。在TIME_WAIT退出后,套接字被删除,该地址才能被重新绑定而不出现问题。

6、注意:
(1)中断连接可以是客户端,也可以是服务端。
假设由客户端中断连接,即客户端发起FIN报文中断连接请求,告诉服务器“我没有数据发给你了”。这时,客户端进入FIN_WAIT_1状态。服务器收到FIN报文后,如果还有数据没有发送完成,则不会急着关闭SOCKET,会继续发送数据。这时,服务器会发送ACK告诉客户端“我收到你的断开请求了,但是我还没有准备好,请等我消息”。这时,客户端就进入FIN_WAIT_2状态,继续等待服务器的FIN报文。当服务器确认数据已经发送完成,则向客户端发送FIN报文,告诉客户端“好了,我这边的数据发完了,准备断开连接”。客户端收到FIN报文后就知道断开连接,但是它不相信网络,怕服务器不知道断开,所以发送ACK后进入TIME_WAIT状态。如果服务器没有收到ACK报文,则客户端会继续重传ACK,服务器收到ACK报文后就知道可以断开连接了。客户端等待2MSL后依然没有收到回复,则证明服务器已正常关闭。那好,我客户端也可以关闭连接了。OK,TCP连接就这样关闭了。

(2)在服务器的TCP连接没有完全断开之前不允许重新监听,某些情况下可能是不合理的。
【例】
服务器需要处理大量的客户端的连接,每个连接的生存时间可能很短,但是每秒都有很多客户端来请求。这个时候,如果由服务器主动关闭连接,比如某些客户端不活跃,就需要被服务器主动清理掉,这时会产生大量的TIME_WAIT连接。由于我们的请求量很大,就可能导致TIME_WAIT的连接数很多而导致服务器的端口不够用,无法处理新的连接。

(3)如何解决TIME_WAIT状态引起的bind失败?
答:使用setsockopt()设置socket描述符的选项SO_REUSEADDR为1,表示允许创建端口号相同,但是IP地址不同的多个socket描述符。即,在server代码的socket函数和bind函数调用之间插入如下代码:
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

详细例子:
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
(1) 建立TCP连接
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80
(2) Web浏览器向Web服务器发送请求命令
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令
例如:GET/sample/hello.jsp HTTP/1.1
(3) Web浏览器发送请求头信息
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
(4) Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答,
HTTP/1.1 200 OK
应答的第一部分是协议的版本号和应答状态码
(5) Web服务器发送应答头信息
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
(6) Web服务器向浏览器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
(7) Web服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

HTTP请求格式
当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:
l 请求方法URI协议/版本
l 请求头(Request Header)
l 请求正文
下面是一个HTTP请求的例子:
GET/sample.jspHTTP/1.1
Accept:image/gif.image/jpeg,/
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=1234
(1) 请求方法URI协议/版本
请求的第一行是“方法URL议/版本”:GET/sample.jsp HTTP/1.1
以上代码中“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本。
根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet应用中,最常用的方法是GET和POST。
URL完整地指定了要访问的网络资源,通常只要给出相对于服务器的根目录的相对目录即可,因此总是以“/”开头,最后,协议版本声明了通信过程中使用HTTP的版本。
(2)请求头(Request Header)
请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
Accept:image/gif.image/jpeg./
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
(3)请求正文
请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:
username=jinqiao&password=1234
在以上的例子的HTTP请求中,请求的正文只有一行内容。当然,在实际应用中,HTTP请求正文可以包含更多的内容。

HTTP请求方法只讨论GET方法与POST方法
l GET方法
GET方法是默认的HTTP请求方法,我们日常用GET方法来提交表单数据,然而用GET方法提交的表单数据只经过了简单的编码,同时它将作为URL的一部分向Web服务器发送,因此,如果使用GET方法来提交表单数据就存在着安全隐患上。例如
Http://127.0.0.1/login.jsp?Name=zhangshi&Age=30&Submit=%cc%E+%BD%BB
从上面的URL请求中,很容易就可以辩认出表单提交的内容。另外由于GET方法提交的数据是作为URL请求的一部分所以提交的数据量不能太大
l POST方法
POST方法是GET方法的一个替代方法,它主要是向Web服务器提交表单数据,尤其是大批量的数据。POST方法克服了GET方法的一些缺点。通过POST方法提交表单数据时,数据不是作为URL请求的一部分而是作为标准数据传送给Web服务器,这就克服了GET方法中的信息无法保密和数据量太小的缺点。因此,出于安全的考虑以及对用户隐私的尊重,通常表单提交时采用POST方法。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!