| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 面试资料-计算机网络 -> 正文阅读 |
|
[网络协议]面试资料-计算机网络 |
网络分层:发送数据时: 最先从应用程开始封装的(定制自己的私有协议),然后再通过网卡封装为MAC帧,再听过网线(物理层)发送出去/ 接收数据时: 最先从网卡开始接收,网卡会通过比对MAC,判断这个数据是发送给自己的,如果是自己的,那么就把解析MAC帧,并继续往上提交. 既然有了MAC帧,为何还要网络层呢? 答案是跨网传播. 因为我们在局域网内传输,同一个局域网内的主机可以直接收到,如果没有网络层,我们跨网传播,那么这个时候,路由会直接懵逼,它回想,这个数据到底是发送到哪里去呢? 局域网内几乎没人应答. 所以IP的作用就是帮助路由完成这部分的工作,告诉路由数据需要发送到哪里去. IP就是类似你的快递的收件地址,借助IP,我们能找到主机的所在地. 中间会这么这么多的节点,节点类似于快递的集散地一样,大家先统一到这一块集散地,然后再分发到各个快递网点,快递网点在分发到各个小区,各个小区的快递员派件的时候再检测下这个快递是否是你的. Q:为什么要分层? A:因为Internet非常复杂。 对于复杂的系统,分层有以下几点好处: 使其结构非常清晰,清楚地知道各层之间的关系; 模块化会使系统的维护、升级更见简化,改变某一层服务的具体实现对系统其他部分透明(不影响)。 But: 分层也有弊端,因为每一层可能都要重复较低层的功能。 物理层: 通信链路与通信节点的连接需要一些电路接口,物理层规定了这些接口的一些参数。物理层还规定了通信链路上传输的信号的意义和电气特征。 数据链路层: 通过物理链路提供可靠的数据传输。涉及物理(而不是逻辑)寻址,网络拓扑,网络访问,错误通知,帧的有序传送以及流量控制。主要的协议有点对点协议PPP。交换机工作在本层。 网络层: 根据IP地址为网络上的两台主机提供连接服务,对分组进行路由选择。并实现流量控制、拥塞控制、差错控制。典型的网络设备是路由器,IP协议为主要的网络协议。路由器工作在本层。 传输层: 负责主机中两个进程之间的通信,为端到端连接提供可靠的传输服务,为端到端连接提供流量控制、差错控制、服务质量、数据传输管理等服务。包含TCP UDP等协议。 会话层: 会话层负责管理主机间的会话进程,包括建立、管理以及终止进程间的会话。 表示层: 主要用于处理在两个通信系统中交换信息的表示方式(数据在页面上的展示方式),表示层还提供数据压缩、加密和解密 应用层: 应用层是用户与网络的接口,应用层需要采用不同的应用该协议来解决不同类型的应用要求。 TCP/IP模型4层 网络接口层: 兼并了物理层和数据链路层,既是传输数据的物理媒介,也可以为网络层提供一条准确无误的线路。接受IP分组,并把它们发送到指定的物理网络上。 网际层: 为两台主机之间提供数据传输服务(路由转发+路由选择),主要的协议为网际协议(IP) 传输层: 为端口之间提供数据传输服务,常见的协议有传输控制协议(TCP),用户数据报协议(UDP) 应用层: 应用程序间进行通信的层,常见的应用层协议有 超文本传输协议(HTTP),简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet) 应用层:支持网络应用,报文传送。HTTP,FTP,SMTP,STTP,系统调用也在该层。 传输层:主机进程间数据段传送。TCP,UDP 网络层:主机(源目标节点)间分组传送。IP协议,ICMP,ARP,路由协议 数据链路层:相邻网络节点间的数据帧传送。PPP,Ethernet,…… 物理层:物理介质上的比特传送 网络应用程序体系结构:1. 客户机/服务器体系结构 服务器主机总是打开 服务器具有固定的、众所周知的IP地址 客户机具有动态的IP地址 客户机之间不能通信 2. P2P体系结构 没有总是打开的服务器 任意一对主机之间可以直接通信 对等方间歇连接,可以改变IP地址 3. 客户机/服务器和P2P混合体系结构 文件在对等方之间相互交换、文件搜索通过服务器 两个聊天用户之间是P2P、注册和查询通过服务器 网络传输基本流程在数据链路层有一个标识:每一台主机的唯一符:MAC地址。 MAC地址:计算机的网卡在出厂时就打上了一串数据:MAC 地址,其通常是唯一的。 所以局域网中发消息必须加上目的主机的MAC地址。 对于MAC地址,由于我们不直接和它接触,所以大家不一定很熟悉。在OSI(Open System Interconnection,开放系统互连)7层网络协议(物理层,数据链路层,网络层,传输层,会话层,表示层,应用层)参考模型中,第二层为数据链路层(Data Link)。它包含两个子层,上一层是逻辑链路控制(LLC:Logical Link Control),下一层即是我们前面所提到的MAC(MediaAccess Control)层,即介质访问控制层。所谓介质(Media),是指传输信号所通过的多种物理环境。常用网络介质包括电缆(如:双绞线,同轴电缆,光纤),还有微波、激光、红外线等,有时也称介质为物理介质。MAC地址也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。这个地址与网络无关,也即无论将带有这个地址的硬件(如网卡、集线器、路由器等)接入到网络的何处,它都有相同的MAC地址,MAC地址一般不可改变,不能由用户自己设定。 mac地址可以标识全世界上唯一一台主机,仅仅在局域网内有效。 ip地址可以标识世界上唯一一台联网的主机,在广域网内也有效 举例子: IP地址是不变的,源地址和目标地址,并且在数据过程中一直不会变的地址。 mac地址,在数据传输过程中是一直在变化的,每次记录当前的源地址和目标地址。 两台计算机通过 TCP/IP 协议通讯的过程如下所示: 首先用户层需要传输文件,那么就需要文件传输协议。 在需要传送的数据加上文件传输协议的报头,呼叫下一层。 传输层接收到这个指令之后,加上该层的协议报头,再呼叫下一层。 网络层收到这个指令之后,加上网络层的报头,传给链路层。 链路层的协议中包括传送目标。通过局域网传送给了对方主机的链路层。 以上过程称为——封装。 不同的协议层堆数据包有不同的称谓: 传输层:段 网络层:数据报 数据链路层:帧 当数据从上层到下层交付的时候,要进行封装,到了堆端之后要进行解包,在解包的时候要决定数据交给上层,还有一个动作叫分用。 数据必须通过物理层(硬件)。 封装:封装数据前加报头,包头后面被封装的叫有效载荷。 解包:每一层报头当中必须要提供一种在那个机制,将报头和有效载荷分离。 分用:解包交付的时候必须要明确要交给上一层的谁。确定交给谁的信息必须在当前层的报头当中包含。(确定信息在当前层的报头) 另一个例子, 消息在网络中的传输过程 PC-A向PC-B传输消息,首先是用户打开消息应用例如QQ,然后给小黑发消息(你吃了吗), 1)在应用层生成数据”你吃了吗(小黑IP)“,然后数据传入表示层节点-表示层, 2)在表示层将数据进行转换(针对计算机系统编码如IBM主机使用EBCDIC编码,而大部分PC机使用的是ASCII码等等的不同)加密,压缩-会话层 3)在会话层将这个qq消息的回话区分出来,然后将会话内容以及相关信息传到下一层-网络层 4)在网络层将会话内容和相关信息(小黑IP)封入数据包-运输层 5)在运输层需要在数据包中插入写信人IP,跟快递一样写明寄件人-数据链路层 6)在数据链路层(对应网卡和相应驱动程序)将小黑IP对应到他的硬件地址(MAC地址网络适配器唯一标识)-物理层 7)在物理层将数据包由帧转换为电信号/光信号,然后通过光纤传输,中途跋山涉水,不断的转发到达目的地,中间万一丢东西了咋办呢,所以这个节点加入了校验值,万一目的地校验后出现了丢失那么重新发送一次,-光纤。 8)剩余的就是和上述相反的过程,由PC-B接收,然后小黑回复(我没喝水)。 ? socket系统调用: 应用层:URIURI 包含 URL 和 URN。 httpHTTP,超文本传输协议,Web的应用层协议,采用客户机/服务器的模式。协议的本质是对信息传输内容和顺序的约定。HTTP协议就约定了客户端与服务器之间通信的标准。 HTTP是无状态协议,服务器不维护客户先前的状态信息。也就是说:如果客户机第一次登录并且成功后,再第二次登录,服务器仍然不会知道当前请求的是哪个用户。 【协议的实现有没有要求客户端或者服务端需要维护一个状态。 比如tcp传输需要经过握手来初始化事务(数据完整性的校验等),所以它是有状态的; 显然http协议本身并没有要求这个,而cookie或session是浏览器和服务器在http协议之上,通过每次给本身并没有状态的请求中添加上某些约定的字段来实现的状态标记。 udp也是无状态传输协议的一种,它只负责发送数据并不需要知道上一次和谁连接过。而如果你每次通过udp传输的时候都带上某个固定字段,实际上这种行为就类似于cookie或session,是应用层的行为而不是协议层。 有状态的,比如BGP路由协议、OSPF路由协议、TFTP文件传输协议。 】 非持久HTTP连接:每个TCP连接只传送一个对象,下载多个对象需要创建多个TCP连接,HTTP/1.0使用非持久HTTP连接。 持久HTTP连接:一个TCP连接可传送多个对象,HTTP/1.1默认使用持久HTTP连接。 http 和 tcp 的区别tcp 是传输层协议, http是应用层协议, HTTP是要基于TCP连接基础上的,在传输层就是使用的tcp,简单的说,TCP就是单纯建立连接,不涉及任何我们需要请求的实际数据,简单的传输。HTTP是用来收发数据,即实际应用上来的。 TCP是底层通讯协议,定义的是数据传输和连接方式的规范 HTTP是应用层协议,定义的是传输数据的内容的规范 HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP也就一定支持TCP Http的首部就是上图中的Appl首部,一条Http请求或者响应协议会被分成N个TCP协议报文,每个TCP报文又被IP报文封装(也就是说TCP报文被分拆到ip报文的数据中),http协议,tcp报文和ip报文头部的内容是不同的,比如IP报文头部由源IP和目的IP信息,TCP报文头部有源端口号和目的端口号信息等 一次完整的http请求过程:浏览器发起请求-> 解析域名得到ip进行TCP连接 ->浏览器发送HTTP请求和头信息发送->服务器对浏览器进行应答,响应头信息和浏览器所需的内容-> 关闭TCP连接或保持-> 浏览器得到数据数据进行操作
一般TCP连接的端口号是80。建立TCP连接需要找到连接主机,所以需要先解析域名得到 IP 再找到主机进行3 次握手建立TCP连接
一旦建立了 TCP 连接,Web 浏览器就会向 Web 服务器发送请求命令。例如:GET/hello/index.jsp HTTP/1.1。
客户机向服务器发出请求后,服务器会客户机进行应答,应答内容包括:协议的版本号和应答状态码 :HTTP/1.1 200 OK,响应头信息来记录服务器自己的数据,被请求的文档内容。最后发送一个空白行来表示头信息的发送到此为结束,接着以Content-Type响应头信息所描述的格式发送用户所请求的实际数据。
一般情况下,一旦 Web 服务器向浏览器发送了请求的数据,它就要关闭 TCP 连接,但是如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive。 TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
浏览器接受服务器应答回来的 html 代码和css,和js代码再进行页面的渲染或者接受到应答的文件进行保存等操作 HTTP报文分为两类: 请求报文; 响应报文。 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协议/版本 以上请求中“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本。 2)请求头(Request Header) 请求头: Accept:指浏览器或其他客户可以接受的MIME文件格式。可以根据它判断并返回适当的文件格式。媒体类型。如:text/html Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859-1. Accept-Language:指出浏览器可以接受的语言种类,如en或en-us,指英语。 Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。 Connection:表示告诉服务器是否需要持久连接。(长连接与短连接) HTTP/1.1使用Keep-Alive(长连接)为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接。数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据。 【注:区分:TCP的keep alive是检查当前TCP连接是否活着;HTTP的Keep-alive是要让一个TCP连接活久点。它们是不同层次的概念。 ??? TCP keep alive的表现:当一个连接“一段时间”没有数据通讯时,一方会发出一个心跳包(Keep Alive包),如果对方有回包则表明当前连接有效,继续监控。】 而Connection: close(短连接)代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。 Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。 Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。 Host(发送请求时,该报头域是必需的) 作用: 请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。 User-Agent作用:告诉HTTP服务器,客户端使用的操作系统和浏览器的名称和版本 3)请求正文 请求头和请求正文之间是一个空行,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息: username=jinqiao&password=1234 在以上的例子中,请求的正文只有一行内容。当然,在实际应用中,HTTP请求正文可以包含更多的内容。 HTTP响应的构成:HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成: 1)状态行 在接收和解释请求消息后,服务器会返回一个HTTP响应消息。 状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔。 格式:????HTTP-Version Status-Code Reason-Phrase CRLF 例如:????HTTP/1.1 200 OK? 状态码: 1XX指示信息--表示请求已接收,继续处理 2XX成功--表示请求已被成功接收、理解、接受 ??? 200 表示从客户端发来的请求在服务器端被正常处理 ??? 204 该状态码表示服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分 206 该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求 3XX重定向--要完成请求必须进行更进一步的操作 ??? 301 永久性重定向 ??? 302 临时性重定向 4XX 客户端错误--请求有语法错误或请求无法实现 ??? 400 该状态码表示请求报文中存在语法错误 ??? 401 该状态码表示发送的请求需要有通过HTTP认证的认证信息 ??? 403 该状态码表明对请求资源的访问被服务器拒绝了。 ??? 404 该状态码表明服务器上无法找到请求的资源 5XX 服务器端错误--服务器未能实现合法的请求 ??? 500 该状态码表明服务器端在执行请求时发生了错误。 ??? 503 该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 2)响应头 响应头可能包括: Location:响应报头域用于重定向接受者到一个新的位置。 Server:响应报头域包含了服务器用来处理请求的软件信息。它和User-Agent请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户 端软件(浏览器)和操作系统的信息。 Content-Encoding:实体报头域被使用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容编码,因而要获得Content- Type报头域中所引用的媒体类型,必须采用相应的解码机制。 Content-Language:实体报头域描述了资源所用的自然语言。Content-Language允许用户遵照自身的首选语言来识别和区分实体。 Content-Length:实体报头域用于指明正文的长度,以字节方式存储的十进制数字来表示,也就是一个数字字符占一个字节,用其对应的ASCII码存储传输。 要注意的是:这个长度仅仅是表示实体正文的长度,没有包括实体报头的长度。 Content-Type:实体报头域用语指明发送给接收者的实体正文的媒体类型。 Last-Modified:实体报头域用于指示资源最后的修改日期及时间。 Expires:实体报头域给出响应过期的日期和时间。 Expires实体报头域使用的日期和时间必须是RFC 1123中的日期格式,例如: Expires: Thu, 15 Sep 2005 16:00:00 GMT 3)响应正文 HTTP和HTTPS的区别主要如下:1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。 2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。 3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。 4、http的连接很简单,是无状态的,协议运行在TCP之上;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全,运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。 注意: HTTPS协议并非是应用层的一种新的协议,只是在HTTP通信接口部分用SSL协议代替而已。原本HTTP与TCP之间直接进行通信,但加入SSL后就先是HTTP与SSL进行通信,再是SSL与TCP进行通信。 HTTP over SSL,在 HTTP 传输上增加了 SSL 安全套接字层,通过机密性、数据完整性、身份鉴别为 HTTP 事务提供安全保证。SSL 会对数据进行加密并把加密数据送往 TCP 套接字,在接收方,SSL 读取 TCP 套接字的数据并解密,把数据交给应用层。HTTPS 采用混合加密机制,使用非对称加密传输对称密钥保证传输安全,使用对称加密保证通信效率。 HTTPS 过程? 1.客户端向服务器发起HTTPS请求,连接到服务器的443端口 2.服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。 3.服务器将自己的公钥发送给客户端。 4.客户端收到服务器端的证书之后,会对证书进行检查,验证其合法性,如果发现证书有问题,那么HTTPS传输就无法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性,下文会进行说明。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。 5.客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。 6.服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。 7.然后服务器将加密后的密文发送给客户端。 8.客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。 SSL协议 SSL:位于TCP/IP协议与各种应用层协议之间。 SSL协议基本内容 SSL记录协议:建立在可靠传输协议的基础之上(如TCP),为高层协议提供数据封装、压缩、加密等基本功能。 SSL握手协议:建立在SSL记录协议之上,在数据传输之前,双方进行身份验证、协商加密算法、交换加密密钥等。 SSL协议原理 公钥加密法。客户端向服务端索要公钥,收到后用自己的私钥加密信息,服务端收到密文后用自己的私钥解密。 注意: SSL协议曾被标准化改名为TLS(传输层安全协议),但这两者其实是同一种协议,只是不同阶段的称呼而已。 HTTP方法:HTTP/1.0方法: GET: 从服务器获取指定数据,用来请求URL指定的资源。指定的资源经服务器端解析后返回响应内容。 POST: 向服务器传送指定数据,传输实体的主体。 HEAD: 服务器收到请求时返回响应消息只包含HEAD头部,不包含请求对象主体。 HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URL的有效性及资源更新的日期时间等。 PUT: 文件在实体主体中被上载到URL指定的路径,传输文件。就像FTP协议的文件上传一样,要求在请求报文主体中包含文件的内容,然后保存到请求URL指定的位置。不太常用。 DELETE: 删除URL字段指定的文件。删除文件,是PUT的相反方法。DELETE方法按请求URL删除指定的资源。也不常用。 HTTP/1.1方法: OPTIONS: 询问支持的方法。用来查询针对请求URL指定的资源支持的方法。 CONNECT: 要求用隧道协议链接代理。要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL和TSL协议把通信内容加密后经网络隧道传输。 HTTP中GET与POST的区别: 1本质定义。GET是从服务器获取数据,POST是把需要处理的数据提交到服务器上。 2安全性。GET方法将请求的数据加在URL后,用 ? 分隔URL和请求数据,多个参数用 & 连接,地址栏中可见,所以非常不安全;POST方法要传送的数据在请求包的实体中,地址栏中不可见,比GET更安全。 3传输数据大小。由于GET方法中请求的数据在URL后面,而URL长度是有限制的,不能超过2KB,因此GET传输的数据较少并且有限;但POST对数据大小没有限制。 4有害性。浏览器后退或者刷新,GET方法不会产生什么动作,也就是不会修改服务器数据,但POST会重新提交数据给服务器。 5 get只能采用unicode编码,而post有多种编码方式。 6 get能被缓存,post不能被缓存。 7 收藏书签:GET可以,而POST不能 HTTP1.0、HTTP1.1 和 HTTP2.0 的区别影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。 带宽:如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。 延迟: 浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。 DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。 建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。 HTTP1.0和HTTP1.1的一些区别:
SPDY:HTTP1.x的优化 优化了HTTP1.X的请求延迟,解决了HTTP1.X的安全性,具体如下:
HTTP2.0和HTTP1.X相比的新特性
HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别?
补充: 全双工(Full Duplex): 一条宽道,通信双方都可以相互发送信息,并且可以同时发送信息。典型的场景比如打电话 半双工(Half Duplex): 一条窄道,通信双方都可以相互发送信息,但是同一时刻只能有一方向另一方发送信息。典型的应用场景比如对讲机。 单工(Simplex): 单行道,通信双方只能有一方向另一方发送消息,典型场景比如打印机。最近研究的netty 就是 异步全双工长连接通信。 注: HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。 HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。
为什么需要头部压缩? 假定一个页面有100个资源需要加载(这个数量对于今天的Web而言还是挺保守的), 而每一次请求都有1kb的消息头(这同样也并不少见,因为Cookie和引用等东西的存在), 则至少需要多消耗100kb来获取这些消息头。HTTP2.0可以维护一个字典,差量更新HTTP头部,大大降低因头部传输产生的流量。
http长连接与短连接:在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。 而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码: Connection:keep-alive 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。 HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。 TCP短连接 模拟一下TCP短连接的情况:client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次请求就完成了。这时候双方任意都可以发起close操作,不过一般都是client先发起close操作。上述可知,短连接一般只会在 client/server间传递一次请求操作。 短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。 TCP长连接 我们再模拟一下长连接的情况:client向server发起连接,server接受client连接,双方建立连接,client与server完成一次请求后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。 TCP的保活功能主要为服务器应用提供。如果客户端已经消失而连接未断开,则会使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,此时服务器将永远等待客户端的数据。保活功能就是试图在服务端器端检测到这种半开放的连接。 如果一个给定的连接在两小时内没有任何动作,服务器就向客户发送一个探测报文段,根据客户端主机响应探测4个客户端状态: 客户主机依然正常运行,且服务器可达。此时客户的TCP响应正常,服务器将保活定时器复位。 客户主机已经崩溃,并且关闭或者正在重新启动。上述情况下客户端都不能响应TCP。服务端将无法收到客户端对探测的响应。服务器总共发送10个这样的探测,每个间隔75秒。若服务器没有收到任何一个响应,它就认为客户端已经关闭并终止连接。 客户端崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。 客户机正常运行,但是服务器不可达。这种情况与第二种状态类似。 长连接和短连接的优点和缺点: 由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。 短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。 长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。?? 而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。 socket和http的区别:Http协议:简单的对象访问协议,对应于应用层。Http协议是基于TCP链接的。 tcp协议:对应于传输层 ip协议:对应与网络层 TCP/IP是传输层协议,主要解决数据如何在网络中传输;而Http是应用层协议,主要解决如何包装数据。 Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。 Http连接:http连接就是所谓的短连接,及客户端向服务器发送一次请求,服务器端相应后连接即会断掉。 socket连接:socket连接及时所谓的长连接,理论上客户端和服务端一旦建立连接,则不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该链接已释放网络资源。所以当一个socket连接中没有数据的传输,那么为了位置连续的连接需要发送心跳消息,具体心跳消息格式是开发者自己定义的。 http缓存:浏览器缓存分为强缓存和协商缓存,浏览器加载一个页面的简单流程如下:
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。 Expires: 缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过,cache-control的优先级更高。 Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。 比如Expires:Thu,31 Dec 2037 23:59:59 GMT。这个时间代表着这个资源的失效时间,也就是说在2037年12月31日23点59分59秒之前都是有效的,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当客户端本地时间被修改以后,服务器与客户端时间偏差变大以后,就会导致缓存混乱。于是发展出了Cache-Control。 Cache-Control: Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。 Cache-Control与Expires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高。 max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置 Cache-Control:max-age=31536000 s-maxage 同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。 public 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。 private 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。 no-cache 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。不是字面意思上的不缓存。 no-store 禁止缓存,每次请求都要向服务器重新获取数据。 must-revalidate指定如果页面是过期的,则去服务器进行获取。这个指令并不常用,就不做过多的讨论了。 协商缓存: 若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。 Last-Modify/If-Modify-Since 浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。 当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。 如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以一致)。于是出现了ETag/If-None-Match。 ETag/If-None-Match 与Last-Modify/If-Modify-Since不同的是,Etag/If-None-Match返回的是一个校验码(ETag: entity tag)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化*。ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。 ETag扩展说明 我们对ETag寄予厚望,希望它对于每一个url生成唯一的值,资源变化时ETag也发生变化。神秘的Etag是如何生成的呢?以Apache为例,ETag生成靠以下几种因子
生成Etag的时候,可以使用其中一种或几种因子,使用抗碰撞散列函数来生成。所以,理论上ETag也是会重复的,只是概率小到可以忽略。 既生Last-Modified何生Etag? 你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题: 1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间 2. 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存 3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。 用户行为与缓存 浏览器缓存行为还有用户的行为有关!!!
DNS协议:用于将域名解析成对应的IP地址。 DNS,全称为Domain Name System,域名系统。是因特网的目录服务,主机、路由器有多种标识符,包括主机名和IP地址。主机名是为了方便人类记忆创建的,是拿给人看的,而IP地址才是用于分组寻址的 ,因为它是固定的长度:32bit,更加规范、路由器更加容易接受。所以我们需要一个转换器,来将主机名转换成IP地址。这时候DNS的作用就出现了,当然,DNS不仅只有这个功能。 从协议上来看:是一种实现域名转换的应用层协议 DNS服务器: 根DNS服务器: 因特网上有13个根DNS服务器,其中大部分分布在美洲。 顶级DNS服务器?负责顶级域名edu, gov, org, com等和所有国家的顶级域名 uk, fr, cn, jp(edu教育机构域名,gov政府部门域名,org非盈利性的组织,com企业域名,uk英国,fr法国,cn中国,jp日本) 权威DNS服务器: 在因特网上具有公共可访问主机(如Web服务器和邮件服务器)的每个组织机构必须提供公共可访问的DNS记录,这些记录将这些主机的名字映射为IP地址。组织机构的权威DNS服务器负责保存这些DNS记录。多数大学和公司维护它们的基本权威DNS服务器。 本地DNS服务器: 严格来说并不属于DNS服务器的层次结构,它起到一个代理的作用,将主机提交的请求转发到层次结构中。 我们以该图为例,来描述DNS的查询过程,一共8条路径(8份报文): (主机cis.poly.edu想要查询主机gaia.cs.umsaa.edu的IP地址) 1主机cis.poly.edu向本地DNS服务器发送查询报文 2本地DNS服务器收到后向根DNS服务器转发查询报文 3根DNS服务器注意到edu域名,返回负责edu的顶级DNS服务器的IP地址 4本地DNS服务器根据收到的IP地址查询顶级DNS服务器 5顶级DNS服务器注意到umass.edu域名,返回负责umass.edu的权威DNS服务器的IP地址。该权威DNS服务器是负责马萨诸塞大学的dns.cs.umass.edu 6本地DNS服务器根据收到的IP地址查询权威DNS服务器dns.cs.umass.edu 7权威DNS服务器dns.cs.umass.edu将使用gaia.cs.umass.edu的IP地址作为响应,返回给本地DNS服务器 8本地DNS服务器将 包含所查询IP地址的报文 返回给主机cis.poly.edu 递归与迭代 递归查询是以本地名称服务器为中心查询, 递归查询是默认方式,迭代查询是以DNS客户端,也就是客户机器为中心查询。 其实DNS客户端和本地名称服务器是递归,而本地名称服务器和其他名称服务器之间是迭代。 1)递归查询 递归查询是一种DNS 服务器的查询模式,在该模式下DNS 服务器接收到客户机请求,必须使用一个准确的查询结果回复客户机。如果DNS 服务器本地没有存储查询DNS 信息,那么该服务器会询问其他服务器,并将返回的查询结果提交给客户机。 2)迭代查询 DNS 服务器另外一种查询方式为迭代查询,DNS 服务器会向客户机提供其他能够解析查询请求的DNS 服务器地址,当客户机发送查询请求时,DNS 服务器并不直接回复查询结果,而是告诉客户机另一台DNS 服务器地址,客户机再向这台DNS 服务器提交请求,依次循环直到返回查询的结果为止。 浏览器中输入url后执行的全部过程一个域名“www.baidu.com.”由4部分组成: 第1部分“.”代表根服务器、 第2部分“.com.”代表顶级域名服务器、 第3部分“baidu.com.”代表域名所有者服务器、 第4部分“www.baidu.com.”代表主机域名。 1. 输入一个url地址 2. 浏览器查找域名的ip地址(域名解析) 导航的第一步是通过访问的域名找出其IP地址。 DNS查找过程如下: 1 浏览器缓存 浏览器会缓存DNS记录一段时间。 操作系统没有告诉浏览器储存DNS记录的时间,不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。 2 系统缓存 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。它会查询本地Host文件,Host的位置因系统而异。这样便可获得系统缓存中的记录。 若Host文件也没有,则向DNS服务器发出查询请求,DNS服务器一般为路由器或 ISP 的缓存 DNS 服务器。 3 路由器缓存 当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客服端的DNS缓存; 4 ISP(互联网服务提供商)DNS缓存 当在用户客服端查找不到域名对应IP地址,则将进入ISP DNS缓存中进行查询。比如你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找; 5 递归查询 若没有,则操作系统将域名发送至?本地域名服务器(本地DNS服务器)- -(递归查询方式),本地域名服务器 查询自己的DNS缓存,查找成功则返回结果, 外部是递归,内部是迭代查询方式: 3.1?本地域名服务器(本地DNS服务器)?向根域名服务器(其虽然没有每个域名的具体信息,但存储了负责每个域,如com、net、org等的解析的顶级域名服务器的地址)发起请求,此处,根域名服务器返回com域的顶级域名服务器的地址。 3.2?本地域名服务器(本地DNS服务器)向com域的顶级域名服务器发起请求,返回baidu.com权限域名服务器(权限域名服务器,用来保存该区中的所有主机域名到IP地址的映射)地址。 3.3?本地域名服务器(本地DNS服务器)向baidu.com权限域名服务器(主域名服务器)发起请求,得到www.baidu.com的IP地址。 如果没有则进入下一级域名服务器进行查找,并重复该步骤直至找到正确纪录。 最后,本地域名服务器(本地DNS服务器)将得到的IP地址返回给操作系统,同时自己也将IP地址缓存起来。 从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是的交互查询就是迭代查询。 接下来就是通过 Socket 发送数据 通过Socket API发送数据,可以选择TCP或UDP协议,一般来说,HTTP常用的是TCP。 3. 建立TCP连接 确认好了IP和端口号,则可以向该IP地址对应的服务器的该端口号发起TCP连接请求。 三次握手: 发送方:SYN(synchronize) 接收方:SYN/ACK(acknowledgement),确认信息传达 发送方:ACK - 确认接收方在线可收消息,握手结束 Accept 浏览器再得到URL后,调用Socket,使用TCP协议,HTTP请求会被封装,加入本地端口,目标端口等信息。IP地址是在IP协议中被封装的。但光有IP地址是不够的,因为设备是可以移动的,IP地址并不与设备绑定。所以还有一个MAC要被封装,每个网卡的MAC地址都是固定且唯一的。这一系列过程就关系到了“TCP/IP协议族”的一个重要的特点:分层。 4. 浏览器给web服务器发送一个HTTP请求 有四种最基本的方法:GET,POST,PUT,DELETE,对应着“查”,“改”,“增”,“删”四个操作。 注意: HTTP是无连接、无状态的,即HTTP在传输完成后就会断开,并且下一次登录时不会记录上次的登录状态。 请求中也包含浏览器存储的该域名的cookies。可能你已经知道,在不同页面请求当中,cookies是与跟踪一个网站状态相匹配的键值。这样cookies会存储登录用户名,服务器分配的密码和一些用户设置等。Cookies会以文本文档形式存储在客户机里,每次请求时发送给服务器。 5. (假如收到状态码301)facebook服务的永久重定向响应 服务器给浏览器响应一个301永久重定向响应,(Location: http://www.facebook.com/),这样浏览器就会访问“http://www.facebook.com/” 而非“http://facebook.com/”。 知道了重定向的新地址后,会重新发送一次新的http请求给新地址。 为什么服务器一定要重定向而不是直接发送用户想看的网页内容呢? 其中一个原因跟搜索引擎排名有关。如果一个页面有两个地址,就像http://www.yy.com/和http://yy.com/,搜索引擎会认为它们是两个网站,结果造成每个搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。还有就是用不同的地址会造成缓存友好性变差,当一个页面有好几个名字时,它可能会在缓存里出现好几次。 301 和 302 重定向的区别? 301 和 302 状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。 他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址; 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。SEO302好于301 重定向的原因? 网站调整(如改变网页目录结构); 网页被移到一个新地址; 网页扩展名改变(如应用需要把.php改成.Html或.shtml)。 这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。 6. 服务器“处理”请求 经过前面的重重步骤,我们终于将我们的http请求发送到了服务器这里,其实前面的重定向已经是到达服务器了,那么,服务器是如何处理我们的请求的呢? 目前大部分的网站会将你的请求到反向代理服务器中,因为当网站访问量非常大,网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。 此时,客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。 通过Nginx的反向代理,我们到达了web服务器,服务端脚本处理我们的请求,访问我们的数据库,获取需要获取的内容等等。 7. 服务器发回一个HTML响应 经过前面的5个步骤,服务器收到了我们的请求,也处理我们的请求,到这一步,它会把它的处理结果返回,也就是返回一个HTPP响应。 HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是: 状态行 响应头(Response Header) 响应正文 关于压缩,头信息说明了是否缓存这个页面,如果缓存的话如何去做,有什么cookies要去设置(前面这个响应里没有这点)和隐私信息等等。 8.关闭TCP连接 四次挥手 9. 浏览器开始显示HTML 在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了。 服务器通过后台语言程序处理,找到数据返回给浏览器,HTML字符串被浏览器接受后被一句句读取解析,解析到link标签后重新发送请求获取css,解析到sript标签后发送请求获取js,并执行代码。 10. 浏览器发送获取嵌入在HTML中的对象 在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。 下面是几个我们访问facebook.com时需要重获取的几个URL: 图片,文件,js等等 11. 浏览器渲染 网页渲染 然后浏览器会进行渲染,浏览器根据HTML和CSS计算得到渲染树,绘制到屏幕上,js会被执行。 总结: 1、输入网址。 2、浏览器查找域名的IP地址。 3. 浏览器给web服务器发送一个HTTP请求 4. 网站服务的永久重定向响应 5. 浏览器跟踪重定向地址 现在,浏览器知道了要访问的正确地址,所以它会发送另一个获取请求。 6. 服务器“处理”请求,服务器接收到获取请求,然后处理并返回一个响应。 7. 服务器发回一个HTML响应 8. 浏览器开始显示HTML 9. 浏览器发送请求,以获取嵌入在HTML中的对象。在浏览器显示HTML时,它会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。这些文件就包括CSS/JS/图片等资源,这些资源的地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等… 案例: 现在假设如果我们在客户端(客户端)浏览器中输入http://www.baidu.com,而baidu.com为要访问的服务器(服务器),下面详细分析客户端为了访问服务器而执行的一系列关于协议的操作: 1、客户端浏览器通过DNS解析到www.baidu.com的IP地址220.181.27.48,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到220.161.27.48,然后通过TCP进行封装数据包,输入到网络层。 2、在客户端的传输层,把HTTP会话请求分成报文段,添加源和目的端口,如服务器使用80端口监听客户端的请求,客户端由系统随机选择一个端口如5000,与服务器进行交换,服务器把相应的请求返回给客户端的5000端口。然后使用IP层的IP地址查找目的端。 3、客户端的网络层不用关系应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,我不作过多的描述,无非就是通过查找路由表决定通过那个路径到达服务器。 4、客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用ARP的请求应答交换的IP数据包现在就可以传输了,然后发送IP数据包到达服务器的地址。 cookies和sessionCookie:由于HTTP协议是无状态协议,所以服务器单从网络连接上无法判断客户端的身份。为了解决这一问题而使用了Cookie技术。就好像说给客户端们每人颁发一个通行证吧,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。 Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。 过程:
常用的:记录上次访问时间;浏览记录 Java中把Cookie封装成了javax.servlet.http.Cookie类。每个Cookie都是该Cookie类的对象。服务器通过操作Cookie类对象对客户端Cookie进行操作。通过request.getCookie()获取客户端提交的所有Cookie(以Cookie[]数组形式返回),通过response.addCookie(Cookiecookie)向客户端设置Cookie。 Cookie对象使用key-value属性对的形式保存用户状态,一个Cookie对象保存一个属性对,一个request或者response同时使用多个Cookie。因为Cookie类位于包javax.servlet.http.*下面,所以JSP中不需要import该类。 Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的Cookie。正常情况下,同一个一级域名下的两个二级域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有helloweenvsfei.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数。 中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。 ?????? Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。 如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。 如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。 如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除。 Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。读者可以通过上例的程序进行验证,设置不同的属性。 使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。但是secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。 如果用户是在自己家的电脑上上网,登录时就可以记住他的登录信息,下次直接访问即可。实现方法是把登录信息如账号、密码等保存在Cookie中,并控制Cookie的有效期,下次访问时再验证Cookie中的登录信息即可。
Session:Session是一种记录客户状态的机制,不同于Cookie的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。 如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。 服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session。典型的场景比如购物车,每个用户的session对就是他的购物车记录,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。 Session对应的类为javax.servlet.http.HttpSession类。每个来访者对应一个Session对象,所有该客户的状态信息都保存在这个Session对象里。Session对象是在客户端第一次请求服务器的时候创建的。Session也是一种key-value的属性对,通过getAttribute(Stringkey)和setAttribute(String key,Objectvalue)方法读写客户状态信息。Servlet里通过request.getSession()方法获取该客户的Session。 Session在服务器端程序运行的过程中创建,当一个用户第一次访问某个网站时会自动创建HttpSession,每个用户可以访问他自己的HttpSession。创建Session的同时,服务器会为该Session生成唯一的session-id,这个session-id在随后的请求中会被用来重新获得已经创建的Session。Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有session-id。当客户端再次发送请求的时候,会将这个session-id带上,服务器接受到请求之后就会依据session-id找到相应的Session,从而再次使用Session。 当多个客户端执行程序时,服务器会保存多个客户端的Session。获取Session的时候也不需要声明获取谁的Session。Session机制决定了当前客户只会获取到自己的Session,而不会获取到别人的Session。各客户的Session也彼此独立,互不可见。 提示:Session的使用比Cookie方便,但是过多的Session存储在服务器内存中,会对服务器造成压力。 ?????? 为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。 由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。 虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。 URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。 区别:
cookie数据存放在客户的浏览器(客户端)上,session数据放在服务器(服务端)上。 Session 的运行依赖Session ID,而 Session ID 是存在 Cookie 中的,也就是说,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 Session ID)。
session为一个用户浏览器独享 cookie为被多个同类型的浏览器共享,可以把cookie想象成一张表
session存在于Session集群也可持久化到DB中; cookie也可持久化,但是会带来安全问题
cookie是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放 session存放于服务器的内存中,所以安全性好 用户验证这种场合一般会用 Session。因此,维持一个会话的核心就是客户端的唯一标识,即Session ID。
Session会占用相当多的资源从而影响性能,可考虑使用Session集群;Session 可以放在 文件、数据库或内存中,比如在使用Node时将Session保存在redis中。由于一定时间内它是保存在服务器上的,当访问增多时,会较大地占用服务器的性能。考虑到减轻服务器性能方面,应当适时使用Cookie。 Cookie则较小
Cookie客户端的限制是4KB;在进行页面cookie操作的时候,应该尽量保证每个域cookie个数小于50个,单条cookie总长度4KB(包阔键和值以及等号)。很多浏览器都限制一个站点最多保存20个cookie。 Session没有对存储的数据量的限制,其中可以保存更为复杂的数据类型。
cookie 只能存储 ASCII 码; Session支持任何类型的数据。
session的生命周期是间隔的,从创建时开始计时,如在20分钟,没有访问session,那么被销毁;但是如果在20分钟内(如在第19分钟时)访问过session,那么,将重新计算session的生命周期。浏览器页面关闭会造成session生命周期的结束,也可以认为生命周期是从浏览器启动到浏览器关闭。 cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束。如果没有设置setMaxAge,则cookie的生命周期当浏览器关闭的时候,就消亡了。即它是预先设置的生存周期,或永久的保存于本地的文件。 token:基于服务器验证方式暴露的一些问题
基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。 NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是否登录。 令牌,是用户身份的验证方式。 最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)。 个人的理解: 由于session是存在服务端的,太占空间了,因此采用cookie明文存储用户信息在本地浏览器中,但是明文的安全性会有问题,考虑到节约服务端的空间与信息的安全性问题,token采用客户端存储的方式,对个人信息进行每次传输前的加密与接收后的解密,保证了安全性的同时,又能够形成一个认证与授权的过程。
基于Token的身份验证的过程如下:
每一次请求都需要token。token应该在HTTP的头部发送从而保证了Http请求无状态。我们同样通过设置服务器属性Access-Control-Allow-Origin:* ,让服务器能接受到来自所有域的请求。 优势: 无状态、可扩展 在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。 如果我们将已验证的用户的信息保存在Session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为Session亲和性)。用户量大时,可能会造成一些拥堵。但是使用tokens之后这些问题都迎刃而解,因为tokens自己hold住了用户的验证信息。 安全性 请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。 token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。 可扩展性 Tokens能够创建与其它程序共享权限的程序。例如,能将一个随便的社交帐号和自己的大号(Fackbook或是Twitter)联系起来。当通过服务登录Twitter(我们将这个过程Buffer)时,我们可以将这些Buffer附到Twitter的数据流上。 使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。 多平台跨域 我们提前先来谈论一下CORS(跨域资源共享),对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。只要用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到。 Token 和 Session 的区别: session和 token并不矛盾,作为身份认证token安全性比session好,因为每个请求都有签名还能防止监听以及重放攻击,而session就必须靠链路层来保障通讯安全了。如上所说,如果你需要实现有状态的会话,仍然可以增加session来在服务器端保存一些状态。 App通常用restful api跟server打交道。Rest是stateless的,也就是app不需要像browser那样用cookie来保存session,因此用session token来标示自己就够了,session/state由api server的逻辑处理。如果你的后端不是stateless的rest api,那么你可能需要在app里保存session.可以在app里嵌入webkit,用一个隐藏的browser来管理cookie session. Session是一种HTTP存储机制,目的是为无状态的HTTP提供的持久机制。所谓Session认证只是简单的把User信息存储到Session里,因为SID的不可预测性,暂且认为是安全的。这是一种认证手段。 而Token,如果指的是OAuth Token或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对App。其目的是让 某App有权利访问 某用户 的信息。这里的Token是唯一的。不可以转移到其它App上,也不可以转到其它 用户 上。 Session只提供一种简单的认证,即有此SID,即认为有此User的全部权利。是需要严格保密的,这个数据应该只保存在站方,不应该共享给其它网站或者第三方App。所以简单来说,如果你的用户数据可能需要和第三方共享,或者允许第三方调用API接口,用Token。如果永远只是自己的网站,自己的App,用什么就无所谓了。 token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件;cookie就是写在客户端的一个txt文件,里面包括你登录信息之类的,这样你下次在登录某个网站,就会自动调用cookie自动登录用户名; token与cookie: Cookie是不允许垮域访问的,但是token是支持的, 前提是传输的用户认证信息通过HTTP头传输; session和cookie差不多,只是session是写在服务器端的文件,也需要在客户端写入cookie文件,但是文件里是你的浏览器编号.Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。 分布式session怎么设计?基于redis存储session方案流程示意图 spring为我们封装好了spring-session,直接引入依赖即可,数据保存在redis中,无缝接入,不存在任何安全隐患;redis自身可做集群,搭建主从,同时方便管理。 现在假定有一个客户,系统通能分为登录和购买两个部分,其中redis数据库存储session信息(正式项目中Redis数据库又分为主从数据库,主服务器负责写,从服务器负责读) 1、用户发送登录请求到服务器1,服务器1接受到请求后创建cookie对象(默认浏览器此时没有cookie对象)和Session对象,Session对象中存放用户登录信息,并获取SessionID将其作为cookie的值。 2、服务器操控Redis数据库创建名为SessionID,值为Session对象的数据信息。 3、服务器返回cookie对象和别的响应信息 4、用户访问服务器2,此时请求头中有值为SessionID的cookie对象和别的信息。 5、服务器通过拦截器拦截cookie中的SessionID,查无此Session,便去Redis数据库中查找 6、将查找结果返回给服务器2,服务器2创建对应的Session对象 7、将创建结果返回给客户端。 负载均衡四层负载均衡:所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。 以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。 七层负载均衡:所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。 在应用层选择服务器,只能先与负载均衡设备进行TCP连接,然后负载均衡设备再与后端服务器建立另外一条TCP连接通道。因此,七层设备在网络性能损耗会更多一些。 以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。 区别: 四层负载均衡与服务器直接建立起TCP连接,很容易遭受SYN Flood攻击。SYN Flood是一种广为人知的DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽的攻击方式。从技术实现原理上可以看出,四层负载均衡很容易将垃圾流量转发至后台服务器,而七层设备则可以过滤这些恶意并清洗这些流量,但要求设备本身具备很强的抗DDOS流量的能力。 常见四层和七层负载均衡设备 四层: F5、LVS等 七层: nginx、apache等 传输层:UDPUDP:用户数据报协议,是一种无连接的传输协议。它只在IP数据报服务之上提供很少一点的功能:即 端口功能 和 差错检测功能 。所以它是“无修饰”、“不加渲染”、“尽最大努力”服务,因此可能会出现的问题: 丢失;报文失序。 UDP的无连接体现在: 接收者与发送者之间没有握手; 每一个UDP数据段的处理独立于其他的数据段(支持一对一、一对多、多对一的数据通信) 从UDP可能出现的问题看起来它很糟糕,那为什么它依然存在并使用着?(优点) 不需要建立连接,所以能减少延迟; 要求简单,发送者与接收者之间不需要保持连接状态; 很小的数据段首部; 没有拥塞控制,会以尽可能快的速度传输 UDP的校验和 即使没有检查到错误,也有可能是错的。差错检测并不是100%可靠,但是尽可能提供了大概率的检错能力。 UDP报文格式:UDP协议分为首部字段和数据字段,其中首部字段只占用8个字节,分别是个占用两个字节的源端口、目的端口、长度和检验和。 TCPTCP与UDP的比较TCP是传输控制协议,是可靠的,面向连接。使用确认,通信双方彼此交换数据前,必须先通过三次握手协议建立连接,之后才能传输数据。检查报文段,丢失或发生错误时(超时)重新发送,提供流量控制,保证可靠交付,保证数据能从一端传到另一端。 UDP是用户数据报协议,是不可靠的,无连接。在数据数据前不用建立连接故而传输速度很快。不检查报文段,不使用确认,不提供流量控制,尽最大努力交付。UDP主要用户流媒体传输,IP电话等对数据可靠性要求不是很高的场合。 ① TCP 是面向连接的,发送数据前必须先建立连接,发送某些预备报文段;UDP 无连接,发送数据前不需要建立连接。 ② TCP 连接是点对点的,只能是单个发送方和单个接收方之间的连接;UDP 支持一对一、一对多和多对多通信。 ③ TCP 提供可靠的交付服务,通过 TCP 传送的数据无差错、不丢失、不重复,按序到达;UDP 使用尽最大努力交付,不保证可靠性,主机不需要维持复杂的连接状态。 ④ TCP 是面向字节流的,TCP 不保证接收方的数据块和发送方的数据块具有对应大小的关系,但接收方的字节流必须和发送方的字节流完全一样。应用程序必须有能力识别收到的字节流,把它还原成应用层数据;UDP 面向报文,对应用层报文添加首部后就交付 IP 层。 ⑤ TCP 有拥塞控制;UDP 没有拥塞控制,网络拥塞不会降低源主机的发送速率,这对某些实时应用很重要,如视频会议。 TCP: HTTP, FTP,SSH,SMTP,POP3,HTTPS UDP: DNS, DHCP(动态主机配置协议,动态配置IP地址),RIP(路由选择信息协议) TCP如何保证可靠性传输1.数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时TCP 发送数据端超时后会重发数据; 2.对失序数据包重排序:既然 TCP报文段作为 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此TCP 报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层; 3.丢弃重复数据:对于重复数据,能够丢弃重复数据; 4.应答机制:当 TCP收到发自 TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒; 5.超时重发:当 TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段; 6.流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 UDP怎么改进来确保可靠传输? 最简单的方式是在应用层模仿传输层TCP的可靠性传输。 下面不考虑拥塞处理,谈谈自己的个人简单粗暴的设计。
1、发送端发送数据时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。发送端收到了ack包后,删除缓冲区对应的数据。 2、时间到后,定时任务检查是否需要重传数据。 实现确认机制、重传机制、窗口确认机制。 如果你不利用Linux协议栈以及上层socket机制,自己通过抓包和发包的方式去实现可靠性传输,那么必须实现如下功能: ???????? 发送:包的分片、包确认、包的重发 ???????? 接收:包的调序、包的序号确认 ???????? 目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。 TCP报文格式:(1)序号(sequence number):seq序号,占32位(4个字节),用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号。 (2)确认号(acknowledgement number):ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。 序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。 (3)标志位(Flags):占1位,共6个,即URG、ACK、PSH、RST、SYN、FIN等。具体含义如下: URG:紧急指针(urgent pointer)有效。 ACK:确认序号有效。仅当ACK=1时,确认号字段才有效。 PSH:接收方应该尽快将这个报文交给应用层。 RST:重置连接。 SYN:发起一个新连接。连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。 FIN:释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接。 (4)剩余的可变动的就是选项和填充。最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。 选项:长度可变,最长可达40字节。当没有使用“选项”时,TCP的首部长度是20字节。 最大报文段长度(MSS)是TCP协议的一个选项,用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度(不包括文段头) 建立连接,三次握手?首先A向B发SYN(同步请求),然后B回复SYN+ACK(同步请求应答),最后A回复ACK确认,这样TCP的一次连接(三次握手)的过程就建立了! 首先,在三次握手建立连接的阶段,是不会传输 TCP 报文段的,传输的是 传输控制块(TCB),传输控制块 TCB(Transmission Control Block)存储了每一个连接中的一些重要信息,如:TCP 连接表,指向发送和接收缓存的指针,指向重传队列的指针,当前的发送和接收序号等等。
由于服务器端不知道要跟谁建立连接,所以其只能被动打开,然后监听端口, 此时 Server 处于 Listen 状态;
然后构建好 TCB 「SYN= 1(表示“请求建立新连接”),seq = x」,发送给服务器端, 此时 Client 会将状态置为 SYN_SEND 「同步已发送」;
同时会构建好 TCB「 SYN = 1,seq = y(表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”), ACK = 1,ack = x + 1(表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值)」发送给客户端;
会将自己的状态改为 ESTABLISHED「建立连接」, 然后发送确认报文 ACK= 1(表示“确认收到服务器端同意连接的信号”), seq = x + 1(表示收到服务器端的确认号Ack,并将其值作为自己的序号值), ack = y + 1(表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值);
至此,三次握手结束,当然在这里,可以带 tcp 报文段信息过来了,因为此时客户端已经可以保证是可靠的传输了,所以在这一端可以发送报文段了。 为什么要三次握手? 首先非常明确的是两次握手是最基本的。第一次握手,客户端发了个连接请求消息到服务端,服务端收到信息后知道自己与客户端是可以连接成功的,但此时客户端并不知道服务端是否已经接收到了它的请求,所以服务端接收到消息后的应答,客户端得到服务端的反馈后,才确定自己与服务端是可以连接上的,这就是第二次握手。 那么为什么需要第三次握手呢?第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误。假设一下如果没有第三次握手,而是两次握手后我们就认为连接成功了,譬如发起请求遇到类似这样的情况:客户端A发出去的第一个连接请求由于某些原因在网络节点中滞留了导致延迟,直到连接释放的某个时间点才到达服务端B,这是一个早已失效的报文,但是此时服务端仍然认为这是客户端的建立连接请求第一次握手,于是服务端回应了客户端,第二次握手。但是A现在并没有向B发送请求,因此不会理睬B的确认,而B却以为连接已经建立,就一直在等,B的很多资源就这样浪费了。 第三次握手假如丢包了怎么办? Server 端: 第三次的ACK在网络中丢失,那么Server 端该TCP连接的状态仍为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包。而Server重发SYN+ACK包的次数,可以修改,默认值为5。如果重发指定次数之后,仍然未收到 client 的ACK应答,那么一段时间后,Server自动关闭这个连接。 Client 端: 在linux中,client 一般是通过 connect() 函数来连接服务器的,而connect()是在 TCP的三次握手的第二次握手完成后就成功返回值。也就是说 client 在接收到 SYN+ACK包,它的TCP连接状态就为 established (已连接),表示该连接已经建立。那么如果 第三次握手中的ACK包丢失的情况下,Client 向 server端发送数据(认为已连接,发送的普通的数据),Server端将以 RST包响应,方能感知到Server的错误。 三次握手过程可以携带数据吗? 第一次和第二次是不可以携带数据的,但是第三次是可以携带数据的。
假如第一次握手可以携带数据的话,那对于服务器是不是太危险了,有人如果恶意攻击服务器,每次都在第一次握手中的SYN报文中放入大量数据。而且频繁重复发SYN报文,服务器会花费很多的时间和内存空间去接收这些报文。
第三次握手的ACK包是可以携带数据。 什么是SYN攻击? Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDoS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了 解决方法: 1)限制单IP并发数 使用iptables限制单个地址的并发连接数量 2)启用syncookies sysctl -w net.ipv4.tcp_syncookies=1 syn cookie技术是对tcp的三次握手进行了一定的修改,但是修改仅在于服务器端,对任何客户端的使用都没有影响。
补充: DoS和DDoS之间的区别: DoS是指拒绝服务,最好定义为尝试使计算机或网络对其预期用户不可用。 在DoS攻击中,部署一台计算机和一个互联网连接,以便用数据包摧毁服务器或网络,其唯一目的是使受害者的带宽和可用资源过载。 DDoS攻击是相同的但是被放大了。DDoS不是一台计算机和一台互联网连接,而是经常涉及数百万台计算机,这些计算机全部以分布式方式使用,以使网站,网络应用程序或网络脱机。 在这两种情况下,无论是通过单一DoS还是多次DDoS攻击,目标都会被数据请求轰炸,这些数据请求会禁用受害者的功能。 常见的攻击: 1.(S)SYN flood(SYN泛洪) SYN泛洪是一种DOS攻击,攻击者向目标系统发送一系列SYN请求,企图使用大量服务器资源使系统对合法流量无响应。 2.Teardrop Attacks(泪滴攻击) 泪滴攻击涉及黑客向受害者的机器发送重叠的,超大的有效载荷的破碎和混乱的IP片段。由于TCP / IP碎片重新组装的方式存在错误,因此显然会导致操作系统和服务器崩溃。所有操作系统的许多类型的服务器都容易受到这种类型的DOS攻击,包括Linux。 3.Low-rate Denial-of-Service attacks(低速拒绝服务攻击) 不要被标题所迷惑,这仍然是致命的DoS攻击!低速率DoS(LDoS)攻击旨在利用TCP的慢速时间动态,能够执行重传超时(RTO)机制以降低TCP吞吐量。简而言之,黑客可以通过发送高速率和密集突发来反复进入RTO状态来创建TCP溢出 - 同时在慢速RTO时间尺度上。受害节点处的TCP吞吐量将大幅降低,而黑客的平均速率较低,因此难以被检测到。 4. Internet Control Message Protocol(ICMP) flood(Internet控制消息协议(ICMP)泛洪)Internet控制消息协议(ICMP)是一种用于IP操作,诊断和错误的无连接协议。ICMP Flood - 发送异常大量的任何类型的ICMP数据包(尤其是网络延迟测试“ping”数据包) - 可能会淹没尝试处理每个传入ICMP请求的目标服务器,这可能导致拒绝 - 目标服务器的服务条件。 5.Peer-to-peer attacks(点对点攻击) 点对点(P2P)网络是一种分布式网络,其中网络中的各个节点(称为“对等体”)充当资源的供应者和消费者,与集中式客户端 - 服务器模型相反,客户端 - 服务器或操作系统节点请求访问中央服务器提供的资源。 断开连接,“四次挥手”:最开始客户端和服务器端都是 ESTABLISHED 的状态,然后客户端会主动关闭,而服务器端则是被动关闭。
FIN=1(表示“请求释放连接”),seq = u + 1「u为结束的报文段序号」, 告诉服务器端,客户端需要关闭了, 此时将客户端的状态变为 FIN-WAIT-1,等待服务器端的反馈;
报文中包括 ACK = 1(表示“接收到客户端发送的释放连接的请求”), seq = v, ack = u+1(表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值), 告诉客户端收到了客户端要关闭的消息了, 同时服务器端会通知应用进程需要关闭连接了,并将自己的状态置为 CLOSE-WAIT; 客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段;
其中 FIN = 1,ACK = 1,(表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。) seq = w,ack = u+1, 告知客户端,服务器端现在可以关闭了, 并将服务器端的状态由 CLOSE-WAIT 变为 LAST-ACK;
ACK = 1,seq = u+1,ack = w+1 告知服务器端,客户端已经知道了你准备好关闭了, 此时会将客户端的状态由 FIN-WAIT-2 置为 TIME-WAIT, 在两个最长报文段传输时间过后,会自动将客户端的状态由 TIME-WAIT 置为 CLOSED。 服务器端收到消息之后,就将状态由 LAST-ACK 置为了 CLOSED,自此,四次挥手全部结束。 为何要四次挥手,不能三次挥手呢? 首先如果去掉最后一次挥手,那么服务器端就不知道自己要关闭的报文有没有传输成功,可能半路上就失败了,但是此时客户端不知道,导致客户端一直在等待服务器关闭,但是此时服务器端直接就关闭了; 如果中间的两次挥手合并,那是肯定不行的,因为此时服务器端可能还有很多报文未处理完,此时直接关闭肯定会对传输有很大影响。 第二次第三次挥手能不能合并? 可以啊,如果服务器端没有剩余报文要发送了,直接可以合并,一起传输。 为什么客户端在收到 服务器端发来的 FIN 包后要等 2 个最长报文段传输时间? 防止最后自己发去的 ack 没传送到服务器,如果服务器没收到客户端的 ack,肯定会选择重发一次 FIN 包,那么此时如果客户端已经关闭了,客户端就不能再发 ack 确认收到了,至于为何是 2 个报文段传输时间,因为刚好一去一回嘛… 2 个最长报文传输时间没有 FIN 包发来,就说明服务器已经关闭了,客户端也就可以安心关闭了。
大量TIMEWAIT出现,并且需要解决的场景 在高并发短连接的TCP服务器上,当服务器处理完请求后立刻按照主动正常关闭连接。。。这个场景下,会出现大量socket处于TIMEWAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。 问题是: 1. 高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他服务要用的,剩下的就更少了。 2. 在这个场景中,短连接表示“业务处理+传输数据的时间 远远小于 TIMEWAIT超时的时间”的连接。这里有个相对长短的概念,比如,取一个web页面,1秒钟的http短连接处理完业务,在关闭连接之后,这个业务用过的端口会停留在TIMEWAIT状态几分钟,而这几分钟,其他HTTP请求来临的时候是无法占用此端口的。单用这个业务计算服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间的比例是 1:几百,服务器资源严重浪费。(说个题外话,从这个意义出发来考虑服务器性能调优的话,长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高) 如何尽量处理TIMEWAIT过多 如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决: 编辑文件/etc/sysctl.conf,加入以下内容: net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 然后执行 /sbin/sysctl -p 让参数生效。 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout 修改系默认的 TIMEOUT 时间 CLOSE_WAIT过多的解决方法 当客户端因为某种原因先于服务端发出了FIN信号,就会导致服务端被动关闭,若服务端不主动关闭socket发FIN给Client,此时服务端Socket会处于CLOSE_WAIT状态(而不是LAST_ACK状态)。 原因分析: close_wait状态出现的原因是被动关闭方未关闭socket造成,此进程在被动关闭后不执行活动关闭,由于没有CLOSE_WAIT超时,连接可以永远保持这种状态(或者至少在程序最终关闭连接或进程存在或被杀死之前)。导致端口被占用光了,其他服务无法运行。 在服务器与客户端通信过程中,因服务器发生了socket未关导致的closed_wait发生,致使监听port打开的句柄数到了1024个,且均处于close_wait的状态,最终造成配置的port被占满出现“Too many open files”,无法再进行通信。 解决方法: 1)原因是因为调用ServerSocket类的accept()方法和Socket输入流的read()方法时会引起线程阻塞,所以应该用setSoTimeout()方法设置超时(缺省的设置是0,即超时永远不会发生);超时的判断是累计式的,一次设置后,每次调用引起的阻塞时间都从该值中扣除,直至另一次超时设置或有超时异常抛出。 比如,某种服务需要三次调用read(),超时设置为1分钟,那么如果某次服务三次read()调用的总时间超过1分钟就会有异常抛出,如果要在同一个Socket上反复进行这种服务,就要在每次服务之前设置一次超时。 2)通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(系统默认超时时间的是7200秒,也就是2小时)。如果服务端程序因某个原因导致系统造成一堆CLOSE_WAIT消耗资源,那么通常是等不到释放那一刻,系统就已崩溃。因此,解决这个问题的方法还可以通过修改TCP/IP的参数来缩短这个时间,于是修改tcp_keepalive_*系列参数: tcp_keepalive_time: /proc/sys/net/ipv4/tcp_keepalive_time INTEGER,默认值是7200(2小时) 当keepalive打开的情况下,TCP发送keepalive消息的频率。建议修改值为1800秒。 tcp流量控制?如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。 (由于TCP是全双工链接,因此发送方和接收方都有滑动窗口) 方法: 利用滑动窗口实现流量控制(也就是发送信息通知发送方自己可以接受数据的大小) 两者区别: 流量控制是端到端的控制,为了解决发送方和接收方速度不同而导致的数据丢失问题,当发送方发送的太快,接收方来不及接受就会导致数据丢失,流量控制用滑动窗口的形式解决问题。如A通过网络给B发数据,A发送的太快导致B没法接收(B缓冲窗口过小或者处理过慢),这时候的控制就是流量控制,原理是通过滑动窗口的大小改变来实现。 拥塞控制是A与B之间的网络发生堵塞导致传输过慢或者丢包,来不及传输。任务是确保子网可以承载所到达的流量。防止过多的数据注入到网络中,导致网络奔溃,超过负荷,这样可以使网络中的路由器或链路不至于过载。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络性能有关的所有因素。当发送方发送数据大量的数据会注入到网络,如果没有限制,网络就会超负荷变卡,拥塞控制的用的是拥塞窗口解决的问题的。 tcp拥塞控制?网络中对资源的需求超过可用量的情况就叫拥塞,当吞吐量明显小于理想吞吐量时就出现了轻度拥塞。拥塞控制就是减少注入网络的数据,减轻路由器和链路的负担,这是一个全局性问题,涉及网络中的所有路由器和主机,而流量控制是一个端到端的问题。 拥塞是:“太多源主机发送太多的数据,速度太快以至于网络来不及处理”。表现为:丢失分组 (路由器的缓冲区溢出)、长延迟 (在路由器的缓冲区排队) 拥塞窗口:发送数据端使用的窗口大小,拥塞窗口不代表缓存,拥塞窗口指某一源端数据流在一个RTT内可以最多发送的数据包数。 当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。因此,较好的方法是先探测一下,即由小到大逐渐增大发送窗口。 TCP四种拥塞控制算法 发送报文段速率的确定,既要根据接收端的接收能力,又要从全局考虑不要使网络发生拥塞,这由接收窗口和拥塞窗口两个状态量确定。 接收端窗口(Reciver Window)又称通知窗口(Advertised Window),是接收端根据目前的接收缓存大小所许诺的最新窗口值,是来自接收端的流量控制。 拥塞窗口cwnd(Congestion Window)是发送端根据自己估计的网络拥塞程度而设置的窗口值,是来自发送端的流量控制。 I. 慢启动: 拥塞窗口一开始为1,先指数增长,至阈值后,再每收到一个ACK再加一,达到网络拥塞后,重新置位1,继续。 II. 拥塞避免: 让拥塞窗口cwnd缓慢的增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd + 1,而不是加倍,即:呈线性增长。这样拥塞窗口cwnd按线性规律缓慢的增长,比慢开始算法的拥塞窗口增长速率缓慢的多。 III. 快重传: 所谓快重传,就是使发送方尽快进行重传,而不是等超时重传计时器超时再重传。 要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认; 即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。 发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等该报文段的超时重传计时器超时再重传。 对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以使整个网络的吞吐量提高约20%。 IV. 快恢复: 发送方一旦收到3个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而执行快恢复算法;发送方将慢开始门限ssthresh值和拥塞窗口cwnd值调整为当前窗口的一半;开始执行拥塞避免算法。(阈值ssthresh的作用是:当下一次出现超时,慢启动到阈值后开始启动拥塞避免。) TCP粘包保护消息边界: 就是指传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。也就是说存在保护消息边界,接收端一次只能接收发送端发出的一个数据包。 流: 而面向流则是指无保护消息保护边界的,如果发送端连续发送数据,接收端有可能在一次接收动作中接收两个或者更多的数据包。 例如,我们连续发送三个数据包,大小分别是2k,4k ,8k,这三个数据包,都已经到达了接收端的网络堆栈中。如果使用UDP协议,不管我们使用多大的接收缓冲区去接收数据,我们必须有三次接收动作,才能够把所有的数据包接收完。而使用TCP协议,我们只要把接收的缓冲区大小设置在14k以上,我们就能够一次把所有的数据包接收下来,只需要有一次接收动作。 这就是因为UDP协议的保护消息边界使得每一个消息都是独立的。而流传输却把数据当作一串数据流,他不认为数据是一个一个的消息。所以有很多人在使用tcp协议通讯的时候,并不清楚tcp是基于流的传输,当连续发送数据的时候,他们时常会认识tcp会丢包。其实不然,因为当他们使用的缓冲区足够大时,他们有可能会一次接收到两个甚至更多的数据包,而很多人往往会忽视这一点,只解析检查了第一个数据包,而已经接收的其他数据包却被忽略了。所以大家如果要作这类的网络编程的时候,必须要注意这一点。 TCP粘包: 指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾。
原因分析:
解决粘包问题的方法 接收方处理时注意分包(发送方注意格式),接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。 格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。 发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。 添加报文长度、 每个报文结尾加分隔符、 报文设置固定长度、 发送方关闭nagle算法 或者,我们可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节(4个自己足够用了) 发送时: 先发报头长度,再编码报头内容然后发送,最后发真实内容。 接收时: 先收报头长度,用struct取出来;根据取出的长度收取报头内容,然后解码,反序列化;从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容。 网络层:发送方:传输报文段到接收方主机 接收方:将收到的报文段递交给传输层 在每个主机、路由器上都需要运行网络层协议。路由器会检查通过它的所有IP数据报的头部字段,然后根据目的IP地址对数据报进行转发。 网络层提供的两个主要功能: 转发(forwarding): 将分组从路由器的输入端口转移到正确的路由器输出端口 路由(routing): 确定分组从发送方传输到接收方(目的主机)所经过的路径(或路由) IP协议:网际协议或互联网协议(Internet Protocol,IP)是用于报文交换网络的一种面向数据的协议,是网络层通信的标准协议,它负责提供基本的数据段传送功能,让每一块数据段都能够到达目的主机,但不检查是否被正确接收。 报文首部结构: 首部长度 ,总长度, 分片相关的 标识符:唯一标识主机发送的每一份数据报。* 标志:分为3个字段,依次为保留位、不分片位和更多片位。 <stron>:该分片相对于原始数据报开始处位置的偏移量。</stron> 生存时间:TTL 协议:TCP/UDP/ICMP 首部校验和:校验接收到的IP数据报是否有差错。 源 IP地址 目的 IP地址 选项 TCP和UDP用一个端口发送信息是否冲突 ? 不会冲突。因为在IP数据报首部有“高层”字段,它定义了传输层的协议。而客户机和服务器会根据IP数据报和TCP/UDP报文段中提供的:传输协议、源IP地址、目的IP地址、源端口、目的端口来判别接收者。 IP 地址 IP地址:分配给主机或路由器接口的标识符。 IP地址有两种:IPV4和IPV6 IPV4:32个二进制位长(4字节),常用点分十进制表示 IPV6:128个二进制位长(16字节)常用冒号分隔表示 IPV4与IPV6:常见的IP 地址,分为IPv4 与IPv6 两大类。 目前现主要使用IPv4 这一类,IPV4 就是有4 段数字,每一段由0~255 数字组成。由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。 所以就有了IPv6的出现,IPv6的使用不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍。IPv6的地址长度为128b,是IPv4地址长度的4倍。 更大的地址空间 IPv4中规定IP地址长度为32,即有2^32-1个地址;而IPv6中IP地址的长度为128,即有2^128-1个地址。 更小的路由表 IPv6的地址分配一开始就遵循聚类(Aggregation)的原则,这使得路由器能在路由表中用一条记录(Entry)表示一片子网,大大减小了路由器中路由表的长度,提高了路由器转发数据包的速度。 增强的组播支持以及对流的支持 这使得网络上的多媒体应用有了长足发展的机会,为服务质量(QoS)控制提供了良好的网络平台. 加入了对自动配置的支持 这是对DHCP协议的改进和扩展,使得网络(尤其是局域网)的管理更加方便和快捷. 更高的安全性 在使用IPv6网络中用户可以对网络层的数据进行加密并对IP报文进行校验,这极大的增强了网络安全 传统的IP地址分类:划分子网网络号相同的IP地址属于同一个网络。而网络还可以划分为若干子网。划分子网的方法是:从主机号借用若干个比特作为子网号,剩下的主机位为主机号。 子网掩码: 子网号字段长度是可变的,因此,为了确定子网地址,IP协议提供了子网掩码的概念 。 子网掩码是一种用来指明一个IP地址所标示的主机处于哪个子网中的标志,子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。 子网掩码用来确定网络地址(包括网络号和子网号)和主机地址的长度。子网掩码长为32位比特,其中的1对应于IP地址中的网络号和子网号,而子网掩码中的0对应于主机号。 路由协议RIP: 路由信息协议 是一种比较简单的内部网关协议,主要用于规模较小的网络,比如校园网以及结构较简单的地区性网络。对于更为复杂的环境和大型网络,一般不使用RIP。RIP是一种基于距离矢量(DV)算法的协议,它通过UDP报文进行路由信息的交换,使用的端口号为520。其使用跳数来衡量到达目的地址的距离,为了限制收敛时间,RIP规定度量值(该值等于从本网络到达目的网络间的路由器数量)为0到15之间的整数,大于等于16的跳数将会定义为网络或主机不可达,因此RIP不适合大型网络。 OSPF: 开放最短路径优先协议 属于链路状态路由协议,OSPF提出了“区域(area)”的概念,每个区域中所有路由器维护着一个相同的链路状态数据库 (LSDB),其使用链路状态数据库,通过最短生成树算法(SPF算法) 计算得到路由表:存放从源节点到每个目的节点的最低费用路径上的下一跳节点。即指出对于发往某个目的节点的分组,从该节点发出后的下一个节点。因此其收敛速度较快。目前OSPF协议在各种网络中广泛部署,目前针对IPv4协议使用的是OSPF Version 2(RFC2328);针对IPv6协议使用OSPF Version 3(RFC2740)。 「ping」命令的作用和原理?简单来说,「ping」是用来探测本机与网络中另一主机之间是否可达的命令,如果两台主机之间ping不通,则表明这两台主机不能建立起连接。ping是定位网络通不通的一个重要手段。 ping 命令是基于 ICMP 协议来工作的,「 ICMP 」全称为 Internet 控制报文协议( Internet Control Message Protocol)。ping 命令会发送一份ICMP回显请求报文给目标主机,并等待目标主机返回ICMP回显应答。因为ICMP协议会要求目标主机在收到消息之后,必须返回ICMP应答消息给源主机,如果源主机在一定时间内收到了目标主机的应答,则表明两台主机之间网络是可达的。 举一个例子来描述「ping」命令的工作过程: 假设有两个主机,主机A(192.168.0.1)和主机B(192.168.0.2),现在我们要监测主机A和主机B之间网络是否可达,那么我们在主机A上输入命令:ping 192.168.0.2 此时,ping命令会在主机A上构建一个 ICMP的请求数据包(数据包里的内容后面再详述),然后 ICMP协议会将这个数据包以及目标IP(192.168.0.2)等信息一同交给IP层协议。 IP层协议得到这些信息后,将源地址(即本机IP)、目标地址(即目标IP:192.168.0.2)、再加上一些其它的控制信息,构建成一个IP数据包。 IP数据包构建完成后,还不够,还需要加上MAC地址,因此,还需要通过ARP映射表找出目标IP所对应的MAC地址。当拿到了目标主机的MAC地址和本机MAC后,一并交给数据链路层,组装成一个数据帧,依据以太网的介质访问规则,将它们传送出出去。 当主机B收到这个数据帧之后,会首先检查它的目标MAC地址是不是本机,如果是就接收下来处理,接收之后会检查这个数据帧,将数据帧中的IP数据包取出来,交给本机的IP层协议,然后IP层协议检查完之后,再将ICMP数据包取出来交给ICMP协议处理,当这一步也处理完成之后,就会构建一个ICMP应答数据包,回发给主机A 在一定的时间内,如果主机A收到了应答包,则说明它与主机B之间网络可达,如果没有收到,则说明网络不可达。除了监测是否可达以外,还可以利用应答时间和发起时间之间的差值,计算出数据包的延迟耗时。 什么是「 ICMP 」?(网络层协议) ping命令是基于ICMP协议来实现的。ICMP协议又是通过IP协议来发送的,即ICMP报文是封装在IP包中。 IP协议是一种无连接的,不可靠的数据包协议,它并不能保证数据一定被送达,那么我们要保证数据送到就需要通过其它模块来协助实现,这里就引入的是ICMP协议。 当传送的IP数据包发送异常的时候,ICMP就会将异常信息封装在包内,然后回传给源主机。 VPN基本原理VPN(Virtual Private Network)技术归为某一类技术,那么将其归为远程访问技术最为合适。 远程访问技术的原理也非常简单,利用一台电脑远距离控制另一台电脑,在这个控制过程中,将TCP/IP协议网络数据通信作为基础,在控制计算机与被控计算机内运行,确保网络通讯等各项功能可以顺利实现。 虚拟即本来不存在的,在网络中指的是“任意两个节点之间的连接并没有传统专网所需的端到端的物理链路,而是架构在公用网络服务商所提供的网络平台” 通过一个简单的例子来说明VPN是如何让两部不同IP的主机进行信息互连。 我们假设有两部VPN Server,且各自都有两块网卡,其中一块连接在因特网,其IP 分别为A 及B 两个公共IP,另外一块网卡则分别连接至192.168.4.0/24 及192.168.6.0/24 两个Private IP 的网段,接着我们来看看192.168.4.10 (下文用a代替)主机如何借助VPN 技术跨越因特网来连接192.168.6.20(下文用b代替)主机. 首先a主机送封包给b主机,当这个封包传送至VPN Server A的位置时,其封包的来源端IP 为a,目的端IP 为b,但是这个封包被送到VPN Server A之后,VPN Server 会把这个封包以特殊的方式来处理,它会把原本的整个封包作为其所要传递的数据内容,并且重新产生一个新的IP 包头,而这个新的IP 包头中的来源端IP 为VPN Server A上的Public IP A,目的端IP 则为VPN Server B上的Public IP B,这样这个封包当然就可以从VPN Server A跨越因特网传送到VPN Server B。待VPN Server B收到这个封包之后,VPN Server B就将新的IP 包头整个去除掉,最后VPN Server B将这个封包送至192.168.6.0/24 的网段上,这样a和b的主机就可以跨越因特网来连接。 其实这种该方法更像是使用A 及B 两个IP 来搭建出一条隧道,然后让a与b 两部主机所传送的封包得以穿梭于隧道之中,这种逻辑上的技术通常被称为Tunnel,而VPN 的隧道技术有很多种方式,刚刚所提到的只是其中的一种罢了。 数据链路层:ARP地址解析协议在以太网环境中,数据的传输所依懒的是MAC地址而非IP地址,而将已知IP地址转换为MAC地址的工作是由ARP协议来完成的。 在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。在以太网中,一个主机和另一个主机进行直接通信,必须要知道目标主机的MAC地址。但这个目标MAC地址是如何获得的呢?它就是通过地址解析协议获得的。所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。 网络层以上的协议用IP地址来标识网络接口,但以太数据帧传输时,以物理地址来标识网络接口。因此我们需要进行IP地址与物理地址之间的转化。 对于IPv4来说,我们使用ARP地址解析协议来完成IP地址与物理地址的转化(IPv6使用邻居发现协议进行IP地址与物理地址的转化,它包含在ICMPv6中)。 ARP协议提供了网络层地址(IP地址)到物理地址(mac地址)之间的动态映射。ARP协议 是地址解析的通用协议。 (在OSI模型中ARP协议属于链路层;而在TCP/IP模型中,ARP协议属于网络层。) APP链接点进后加载一段时间后仍无内容,分析可能的情况1网络信号差 2DNS解析慢 3建立链接慢 当我们获取到服务器IP后,客户端和服务器建立连接,这个链接的速度与质量取决于线路的优劣。最常见的问题就是跨线路访问,地理位置相差很远的访问,中继网络异常等。排查方法:如果ping一个网址,存在大量丢包或者很高延迟(国内ping延迟超过50ms),就会导致访问的连接线路异常。 4服务器响应慢 当一个服务器健康运行,这个时间几乎可忽略,但是如果服务器不那么健康,比如CPU,内存,磁盘,带宽,只要一个达到瓶颈的服务器就是亚健康,将直接影响访问速度。排查方法:如果此前访问很快的网站访问突然变慢了,在网络无问题的情况下,云主机可查看内部资源使用情况;虚拟主机则可通过执行简单命令或直接访问图片来判断服务器资源占用情况。 5本身问题,加载速度慢 加载时间慢可以说是最明显、最大程度影响访问速度的因素了。当用户访问一个网站时候,服务器会向客户端发送大量的内容,这会占用大量的服务器带宽。带宽就是最常见也是最直接影响打开的因素。 什么是防火墙? 防火墙对流经它的网络通信进行扫描,这样能够过滤掉一些攻击,以免其在目标计算机上被执行。防火墙还可以关闭不使用的端口。而且它还能禁止特定端口的流出通信,封锁特洛伊木马。最后,它可以禁止来自特殊站点的访问,从而防止来自不明入侵者的所有通信。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 17:33:11- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |