赞
踩
目录
第1层 物理层
首先解决两台物理机之间的通信需求,具体就是机器A往机器B发送比特流,机器B能收到比特流。
物理层主要定义了物理设备的标准,如网线的类型,光纤的接口类型,各种传输介质的传输速率。主要作用是传输比特流(0101二进制数据),将比特流转化为电流强弱传输,到达目的后再转化为比特流,即常说的数模转化和模数转换。这层数据叫做比特。网卡工作在这层。
第2层 数据链路层
在传输比特流的过程中,会产生错传、数据传输不完整的可能。
数据链路层定义了如何格式化数据进行传输,以及如何控制对物理介质的访问。通常提供错误检测和纠正,以确保数据传输的准确性。本层将比特数据组成帧,交换机工作在这层,对帧解码,并根据帧中包含的信息把数据发送到正确的接收方。
第3层 网络层
随着网络节点的不断增加,点对点通讯需要通过多个节点,如何找到目标节点,如何选择最佳路径成为首要需求。
网络层主要功能是将网络地址转化为对应的物理地址,并决定如何将数据从发送方路由到接收方。网络层通过综合考虑发送优先权、网络拥塞程度、服务质量以及可选路由的花费来决定从一个网络中节点A到另一个网络中节点B的最佳路径。由于网络层处理并智能指导数据传送,路由器连接网络隔断,所以路由器属于网络层。此层的数据称之为数据包。本层需要关注的协议TCP/IP协议中的IP协议。
第4层 传输层
随着网络通信需求的进一步扩大,通信过程中需要发送大量的数据,如海量文件传输,可能需要很长时间,网络在通信的过程中会中断很多次,此时为了保证传输大量文件时的准确性,需要对发送出去的数据进行切分,切割为一个一个的段落(Segement)发送,其中一个段落丢失是否重传,段落是否按顺序到达,是传输层需要考虑的问题。
传输层解决了主机间的数据传输,数据间的传输可以是不同网络,并且传输层解决了传输质量的问题。传输协议同时进行流量控制,或是基于接收方可接收数据的快慢程度规定适当的发送速率。除此之外,传输层按照网络可处理的最大尺寸将较长的数据包进行强制分割,例如以太网无法接收大于1500字节的数据包,发送方节点的传输层将数据分割成较小的数据片并编号,以便数据到达接收方节点的传输层时能以正确的顺序重组,该过程称为排序。传输层需要关注的协议有TCP/IP协议中的TCP协议和UDP协议。
第5层 会话层
自动收发包,自动寻址。
会话层作用是建立和管理应用程序间的通信。
第6层 表示层
Linux给WIndows发包,不同系统语法不一致,如exe不能在Linux下执行,shell不能在Windows不能直接运行。于是需要表示层。
解决不同系统之间通信语法问题,在表示层数据将按照网络能理解的方案进行格式化,格式化因所使用网络的不同而不同。
第7层 应用层
规定发送方和接收方必须使用一个固定长度的消息头,消息头必须使用某种固定的组成,消息头中必须记录消息体的长度等信息,方便接收方正确解析发送方发送的数据。应用层旨在更方便应用从网络中接收的数据,重点关注TCP/IP协议中的HTTP协议。
从应用层开始对要传输的数据头部进行处理,加上本层的一些信息。最终物理层通过以太网、电缆等介质将数据解析成比特流在网络中传输,数据传递到目标地址,自底而上的将先前对应的头部解析分离出来。
OSI的实现“TCP/IP”
OSI七层网络模型 | TCP/IP四层概念模型 | 对应网络协议 |
应用层(Application) | 应用层 | HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层(Presentation) | Telnet, Rlogin, SNMP, Gopher | |
会话层(Session) | SMTP, DNS | |
传输层(Transport) | 传输层 | TCP, UDP |
网络层(Network) | 网络层 | IP, ICMP, ARP, RARP, AKP, UUCP |
数据链路层(Data Link) | 数据链路层 | FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理层(Physical) | IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
IP、TCP、UDP、HTTP等都属于TCP/IP协议,TCP/IP泛指这些协议。
OSI模型注重通信协议必要的功能;TCP/IP更强调在计算机上实现协议应该开发哪种程序。
IP协议是无连接的通信协议,不会占用两个正在通信的计算机之间的通信线路。降低了对网络线路的需求,每条线同时满足许多不同计算机之间的通信需要。通过IP,消息或其他数据被分割为较小的独立的包,并通过因特网在计算机之间传送。IP负责将每个包路由至目的地。IP协议没有确认包是否按顺序发送,或包是否被破环,因此IP数据包是不可靠的。需要它的上层协议做出控制。
1)面向连接的、可靠的、基于字节流的传输层通信协议
2)将应用层的数据流分割成报文段并发送给目标节点的TCP层
3)数据包都有序号,对方收到则发送ACK确认,未收到则重传
4)使用校验和来检验数据在传输过程中是否有误
参考:百度百科_TCP_简介
应用层向TCP层发送数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元MTU的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认ACK;如果发送端实体在合理的往返时延RTT内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
参考:TCP分段与IP分片
端口:两个进程在计算机内部进行通信,有管道、内存共享、信号量、消息队列等方法。两个进程通信最基本的前提是唯一标识一个进程,通过唯一标识找到对应的进程。在本地进程通信中可以通过pid,但pid只在本地唯一。如果把两个进程放到两台计算机通信,pid实现不了。解决这个问题的方法就是在传输层使用协议端口号,简称端口。IP地址可以唯一标识主机,TCP协议和端口号可以唯一标识主机中的一个进程,利用IP地址+协议+端口号唯一标识去标识网络中的一个进程,这种唯一标识的模式称为Socket。
seq序号:占4字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如:一段报文的序号字段值是107,携带的数据是100个字段,下一个报文段序号从107+100=207开始。
ack确认号:4个字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如:B收到A发送的报文,其序号字段是301,数据长度是200字节,表明B正确收到A发送的到序号500为止的数据(301+200-1=500),B期望收到A下一个数据序号是501。B发送给A的确认报文段中把ack确认号置为501。
数据偏移:头部有可选字段,长度不固定,指出TCP报文段的数据起始处距离报文段的起始处有多远。
保留:保留今后使用的,被标为1。
控制位:由8个标志位组成。每个标志位表示一个控制功能。
其中主要的6个:
URG紧急指针标志,为1表示紧急指针有效,为0忽略紧急指针。
ACK确认序号标志,为1表示确认号有效,为0表示报文不含确认信息,忽略确认号字段。上面的确认号是否有效就是通过该标识控制的。
PSHpush标志,为1表示带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将该报文段交给应用程序,而不是在缓冲区排队。
RST重置连接标志,重置因为主机崩溃或其他原因而出现错误的连接,或用于拒绝非法的报文段或非法的连接。
SYN同步序号,用于建立连接过程,在连接请求中SYN=1和ACK=0表示该数据段没有使用捎带的确认域,连接应答捎带一个确认即SYN=1和ACK=1。
FIN终止标志,用于释放连接,为1时表示发送方没有发送了。
窗口:滑动窗口大小,用来告知发送端接收端缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。
校验和:奇偶校验,此校验和是对整个的TCP报文段(包括TCP头部和TCP数据),以16位进行计算所得,由发送端计算和存储,接收端进行验证。
紧急指针:只有控制位中的URG为1时才有效。指出本报文段中的紧急数据的字节数。
选项:其长度可变,定义其他的可选参数。
当应用程序希望通过TCP与另一个应用程序通信时,会发送一个通信请求,这个请求必须发送到一个确切的地址,双方握手之后,TCP建立一个全双工的通信(计算机A能给B发送信息,在发送信息的同时B也能给A回发信息。半双工通信:双向交替通信,即通信的双方都可以发送信息,但不能双方同时发送和接收),这个通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。握手即为TCP三次握手。
首先假设A和B首次通信,客户端和服务器端处于CLOSED的状态,假设主动打开连接的是客户端,被动打开连接的是服务器端。TCP服务器进程先创建传输控制块TCB,时刻准备接收其他客户进程发送的连接请求,此时服务端进入Listen即监听状态。TCP客户端进程创建传输控制块TCB,向服务器发出连接请求报文,TCP请求报文中的同步序号SYN=1,同时选择一个初始序号seq=x,x为任意的正整数值。TCP客户端进程进入SYN-SENT同步已发送状态,发送过去的报文段称为SYN报文段,不携带数据,但消耗掉一个序号,这便是第一次握手。
当服务器接收到请求报文后,如果同意连接,则发出确认报文,确认报文中包含ACK=1,SYN=1,确认号ack=x+1(SYN报文中指定seq=x,作为回应回应和x相关的信息,上面的报文消耗掉一个序号,因此为x+1),同时为自己的缓存初始化一个序列号即seq=y。服务器进入SYN-RCVD即同步收到的状态,这个报文也不携带数据,同样消耗一个序号,这便是第二次握手。
TCP客户进程收到确认报文后还要向服务器给出一个确认,确认报文ACK=1,ack=y+1(服务器给发了seq=y,作为回应ack,同时报文消耗一个序号seq,回应就是y+1),先前告知序号seq已经被加1了,seq=x+1。此时TCP连接建立,客户端进入ESTAB-LISHED建立连接的状态,TCP规定这个ACK报文段可以携带数据(前两个不携带),也可以不携带,不携带就不会消耗序号,这便是第三次握手。服务器收到客户端的确认后,也会进入ESTAB的状态,双方就可以通信了。
简介如下:
TCP 为什么三次握手而不是两次握手?
在前两次握手的时候双方都随机选择了自己的初始段序号,并且第二次握手的时候连接请求发送端收到了自己的ack number,确认了自己的序列号,而连接请求响应端还没有确认自己的序列号,没有收到ack number。 如果这时候两次握手下就进行数据传递, 序号没有同步,数据就会乱序。
参考:TCP 为什么三次握手而不是两次握手、彻底搞懂TCP协议:从 TCP 三次握手四次挥手说起
挥手即终止TCP连接,即断开一个TCP连接时,需要客户端和服务端总共发出四个包,以确认连接的断开。在Socket编程中,这一过程由客户端或服务端任一方执行CLOSE来触发。假设由客户端主动促发CLOSE。
开始时客户端和服务端都处于ESTAB的状态,客户端主动关闭,服务器被动关闭。首先客户端发出连接释放报文,并且停止发送数据,FIN=1,假设客户端定义的序列号seq=u(该值等于前面ESTAB状态下数据最后一次发送时已经传送过来数据的最后一个序号+1)。此时客户端进入FIN-WAIT-1终止等待1的状态,TCP规定即使FIN报文不携带数据也要消耗掉一个序号,即回执时u+1。当服务器收到连接释放报文之后发出确认报文ACK=1,作为回应ack=u+1,携带上自己的序列号seq=v。服务端进入CLOSE-WAIT关闭等待的状态。TCP服务器通知高层的应用进程,客户端要释放跟服务器通信的连接,这时处于半关闭的状态,即客户端已经没有数据发送,服务器要发送数据,客户端还可以接收,这个状态持续一段时间,该时间等于CLOSE-WAIT所持续的时间。客户端收到服务器的确认请求后即第二次挥手时客户端进入FIN-WAIT2即终止等待2状态,等待服务器发送释放连接报文,即等待发送第三次挥手的请求。在这段时间可能接收服务器发送的最后的数据,服务器将最后的数据发送完毕后,向客户端发送连接释放报文,FIN=1,ACK=1,ack=u+1,在半关闭的状态,服务器可能发送了一些数据,假设seq变为w,此时服务器进入LAST-ACK即最后确认状态,等待客户端的最终确认。客户端在收到服务器的连接释放报文后必须发出确认即ACK=1,ack=w+1回发回去,自己的序号按之前报文 的序号加1即seq=u+1,客户端进入TIME-WAIT时间等待状态,此时客户端的TCP连接还没有释放,必须经过2*MSL时间后连接才真正释放,进入CLOSE状态。MSL即最长报文段寿命。服务器只要收到客户端发出的确认,立即进入CLOSE的状态。服务器结束TCP连接时间比客户端稍早些。
为什么会有TIME_WAIT状态?为什么不直接为CLOSE状态?
确保有足够的时间让对方收到ACK包(被动关闭的一方没有收到ACK,会触发被动端重发FIN包,一来一回就是2MSL)
避免新旧连接混淆(有些路由器会缓存IP数据包,如果连接被重用,延迟收到的包有可能会跟新连接混在一起)
为什么需要四次挥手才能断开连接?
因为TCP是全双工,发送方和接收方都需要FIN报文和ACK报文。发送方和接收方各需两次挥手,一方是被动的,看上去就是四次挥手。
服务器出现大量CLOSE_WAIT状态的原因?
其中一个表现是客户端一直在请求,返回给客户端的信息是异常的,服务端没有收到请求。
对方关闭socket连接,我方忙于读或写,没有及时关闭连接
检查代码,特别是释放资源的代码
检查配置,特别是处理请求的线程配置
UDP用户数据报协议,相比TCP报文,UDP报文的域少了很多,简单很多
1)面向非连接(传输数据之前,源端和终端不建立连接。当它想传送时,就简单抓取来自应用程序的数据,并尽可能快的把它扔到网络上。在发送端,UDP传送数据的速度仅仅受应用程序生成数据的速度、计算机能力、传输带宽的限制。在接收端,UDP把每个消息段放入队列中,应用程序每次从队列中读取一个消息段。)
2)不维护连接状态,支持同时向多个客户端传输相同的消息
3)数据包报头只有8个字节,额外开销较小
4)吞吐量只受限于数据生成速率、传输速率以及机器性能
5)尽最大努力交付,不保证可靠交付,不需要维持复杂的链接状态表
6)面向报文,不对应用程序提交的报文信息进行拆分或者合并
TCP提供可靠的通信传输,UDP常被用于让广播和细节控制交给应用层的通信传输
区别如下:
1)面向连接VS无连接
TCP面向连接,UDP面向无连接。TCP有三次握手的连接过程;UDP适合消息的多播发布,从单个点向多个点传输信息。
2)可靠性
TCP可靠,利用握手确认和重传机制提供可靠性保证;UDP可能丢失,不知道到底有没有接收。
重传机制:一是基于时间(设置一个计时器来判断数据传输是否超时),二是基于确认信息(TCP等待一定数目的重复ACK,来决定数据是否丢失并触发快速重传)。
参考:TCP重传机制
3)有序性
TCP利用序列号保证消息报的顺序交付,到达可能无序,但TCP最终排序;UDP不具备有序性
4)速度
TCP速度慢,因为需要创建连接,保证消息的可靠性、有序性,需要做额外的操作;UDP更适合对速度比较敏感的应用,比如在线视频媒体、电视广播、多人在线游戏。
5)量级
TCP属于中级,UDP属于轻量级。体现在源数据的头大小,TCP是20个字节,UDP是8个字节。
RTT:发送一个数据包到收到对应的ACK,所花费的时间
RTO:重传时间间隔(TCP在发送一个数据包后会启动一个重传定时器。RTO即定时器的重传时间)
开始预先算一个定时器时间,如果回复ACK,重传定时器就自动失效,即不需要重传;如果没有回复ACK,RTO定时器时间就到了,重传。RTO是本次发送当前数据包所预估的超时时间,RTO不是固定写死的配置,是经过RTT计算出来的。基于RTO便有了重传机制。
TCP将数据拆分成段进行发送,出于效率和传输速率的考虑,不可能一段一段数据发送,等上一段数据确认后再发送下一段数据,效率低。要实现对数据的批量发送,TCP解决可靠传输和包乱序的问题,所以TCP需要知道网络实际的数据处理带宽或数据处理速度,这样才不会引起网络拥塞导致丢包。
TCP使用滑动窗口做流量控制与乱序重排。
TCP的滑动窗口主要有两个作用:
1)保证TCP的可靠性
2)保证TCP的流控特性
TCP报文头有个字段叫Window,用于接收方通知发送方自己还有多少缓存区可以接收数据,发送方根据接收方的处理能力来发送数据,不会导致接收方处理不过来,这便是流量控制。
窗口数据的计算过程:
上图左面是TCP的发送端缓冲区,右面是接收端缓冲区,左面往右边发送数据。下面的长方形表示要发送的数据流,里面假设装满数据,并且按照顺序从左向右发送或者接收。假设对应的数据段位置序号也是从左到右。
对于发送方LastByteAcked指向收到的连续最大的ACK的位置,即从左端算起连续已经被接收程序发送ACK回执确认已收到的seq num。LastByteSent指向已发送的最后一个字节的位置,该位置只是发出去了,还没收到ACK的回应。LastByteWritter指向上层应用已写完的最后一个字节的位置,即当前程序已经准备好的需要发送的最新的数据段。从LastByteAcked到LastByteSent是发送出去还没收到确认的,LastByteAcked之前是已经发送出去并且收到接收端确认的。
对于接收方LastByteRead指向上层应用已经读完的最后一个字节的位置,即收到发送方数据,已经处理并且回执数据的最后一个位置。NextByteExpected指向收到的连续最大的seq的位置。从LastByteRead到NextByteExpected是已经收到还没发送回执。LastByteRecvd是已收到的最后一个字节的位置。NextByteExpected到LastByteRecvd有些seq还没有到达,对应空白区域。可以根据上面的数值计算出接收方AdvertisedWindow的大小,回发给发送方让其计算出发送方的剩余和发送的数据大小,即EffectiveWindow 的大小。
接收方还能处理的数据的量AdvertisedWindow = MaxRcvBuffer - (LastByteRcvd - LastByteRead)
MaxRcvBuffer:接收方能接收的最大数据量,也可以理解为接收端缓存池的大小。
LastByteRcvd-LastByteRead表示的是当前接收方已为接收到的数据或还没有接收到的预定的数据留出来的空间。当前这些空间已经占据一定的缓存,用最大的缓存减去已经占据的缓存得出还能够接收的数据量。进而可以将AdvertisedWindow告知发送端。发送方根据ACK中AdvertisedWindow的值需要保证LastByteSent-LastByteAcked<=AdvertisedWindow,即已发送且带确认的数据量小于接收方的windows大小
窗口内剩余可发送数据的大小EffectiveWindow = AdvertisedWindow - (LastByteSent - LastByteAcked)
LastByteSent-LastByteAcked是发送出去待确认的,以接收方能够承受的数据量AdvertisedWindow为基准,当前已经发了LastByteSent-LastByteAcked还没有被接收,剩下的空间是还能够发送的数据量的大小。
在其发送缓存内的数据可以分为4类:已经发送并且得到端的回应的、已经发送但还没收到端的回应的、未发送但对端允许发送的、未发送且由于达到window的大小对端不允许发送的。已经发送但还没收到对端ACK确认的、未发送但对端允许发送的组成滑动窗口。
当收到接收方新的ACK对于发送窗口中后序字节的确认时,窗口就会滑动。滑动原理如下:假设原滑动窗口边界是32到51,假设已发送但还未被确认的序号是32到40。如果32和33没被确认,34被确认,这个窗口不会向右滑动,只有等到32到34都被确认之后即连续被确认之后滑动窗口才会被移动。在没被移动之前,序号>=52的数据即窗口外的数据是不能被发送的。假设从32到35都被确认了,滑动窗口会向右移动4位到36,进而程序能够发送52到55的数据。
某一时刻在接收缓存内会存在三种状态:已接收已发送回执的状态,未接收但可以接收(准备接收)的状态、未接收不能接收的状态(达到窗口的阈值不能接收)。由于ACK直接由TCP栈回复,默认没有应用延迟,不存在已接收但未回复ACK的状态。未接收准备接收的空间称为接收窗口。TCP传输可靠性来自确认重传机制,TCP滑动窗口的可靠性也建立在确认重传机制的基础上。发送窗口只有收到接收端对于本段发送窗口内字节的ACK确认,才会移动发送窗口的左边界,接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当前面还有字节未接收但收到后面字节的情况下窗口不会移动,并不对后续字节确认,以此确保对端会对这些数据重传。
滑动窗口的大小可以根据一定策略动态调整,应用会根据自身处理能力的变化,通过本端TCP接收窗口的大小控制来实现对端的发送窗口进行流量限制。
参考:计算机网络:流量控制和拥塞控制、TCP流量控制和拥塞控制、TCP流量控制和拥塞控制、TCP的阻塞和重传机制
HTTP是基于请求与响应模式的无状态的应用层协议。绝大多的web开发是构建在HTTP协议上的web应用。
特点:
1)支持客户/服务器模式:浏览器作为HTTP客户端通过URL向HTTP服务端即web服务器发送请求,web服务器根据接收到的请求向客户端发送响应信息。
2)简单快速:客户端向服务器请求服务时只需传送请求方法和路径,请求方法常用的有get、head、post。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,HTTP服务器程序规模小,因而通信快。
3)灵活:HTTP允许传输任意类型的数据对象,正在传输的类型由Content-Type加以标记。
4)无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。从HTTP1.1起默认使用长连接,即服务器需要等待一定时间后才断开连接,以保证连接特性。目前的技术如keep-alive使用长连接优化效率,但这些属于HTTP请求之外。在每个独立的HTTP请求中,无法知道当前的HTTP是否处于长连接状态,始终认为HTTP请求在结束后连接就会关闭,这是HTTP的特性。下层实现是否在结束请求后关闭连接都不会改变这个特性。长连接可以理解为下层实现对上层透明。
5)无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP协议目前处于多个版本共存的情况,包括仍被广泛采用的1.0、主流最为广泛的1.1、应用较少吹的最大的2.0。1.1较1.0引入了Keep-Alive长连接技术。2.0更合理更先进但推广不开的原因是1.1完全能够满足目前的应用,并且升级上2.0成本太大。以下以1.1为准。
参考:HTTP1.0 HTTP1.1 HTTP2.0 主要特性对比、HTTP1.0、HTTP1.1 和 HTTP2.0 的区别、HTTP/2 相比 1.0 有哪些重大改进?
客户端发送一个HTTP请求到服务器的请求消息结构如下:
Request Header:
Accept:浏览器可接收的数据格式
Accept-Encoding:浏览器可接收的压缩算法,如gzip
Accept-Language:浏览器可接收的语言,如zh-CN
Connection:keep-alive 一次TCP连接重复使用
cookie:缓存
Host:域名
User-Agent(UA):浏览器信息
Content-type:发送数据的格式,post请求,如application/json
1)请求行:请求方法post、get、put等等;协议版本HTTP1.0、1.1
2)请求头部:由若干个报头组成,每个报头都是名字+分号+空格+值,名字是大小写无关的。报头用来设置HTTP请求的参数,例如Host表示被请求资源的主机端口号,还有常用的头部字段Content-type
3)空格:数据体和头部之间有空行。请求头部后的空行是必须的,即使第四部分的请求数据为空。浏览器发送空行通知服务器结束了头信息的发送。
4)请求数据:请求正文、数据体。只在post请求中用到,表示要上传的数据。
eg:
HTTP响应结构:
Response Header:
Content-type:返回数据的格式
Content-length:返回数据的大小,多少字节
Content-Encoding:返回数据的压缩算法,如gzip
Set-Cookie:修改Cookie
Cache-Control:是否缓存
Expires:已被Cache-Control代替
Last-Modifie: 资源的最后修改时间
Etag:资源的唯一标识
服务器接收并处理客户端发来的请求后会返回HTTP的响应消息,即响应报文。
1)状态行:协议版本、状态码、状态码描述
2)响应头部:说明客户端附加信息,例如Content-type指定了MIME类型的HTML
3)响应的正文
HTTP协议定义了web客户端如何从web服务器请求web页面,以及服务器如何把web页面返回给客户端。HTTP协议采用请求响应模型,客户端向服务器发送一个请求报文,请求报文包含请求方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包含协议的版本、成功或错误的代码、服务器信息、响应头部和响应数据。
1)客户端连接到web服务器:HTTP客户端通常是浏览器,与web服务器的HTTP端口(默认端口号80)建立TCP套接字连接。
2)发送HTTP请求:通过TCP套接字客户端向web服务器发送文本请求报文。
3)服务器接受请求并返回HTTP响应:web服务器解析该请求定位请求资源,服务器将资源副本写入TCP套接字,由客户端读取。
4)释放TCP连接,若连接模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接。若连接模式为Keep-Alive,则该连接会保持一段时间,在该时间内可以继续接收请求。
5)客户端浏览器解析HTML内容:客户端浏览器首先解析状态行,查看表明请求是否成功的状态码,解析每个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML根据HTML语法对其进行格式化,并在浏览器窗口中显示。
忽略掉诸如键盘事件响应之类的,只关心跟网络相关的知识。考虑最简单的流程。
1)DNS解析:浏览器会依据URL逐层查询DNS服务器缓存,解析URL中的域名对应的IP地址,DNS缓存从近到远依次是浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、域名服务器缓存、顶级域名服务器缓存。从哪个缓存找到对应的IP直接返回,不再查询后面的缓存。
2)TCP连接:结合三次握手
3)发送HTTP请求:浏览器发出读取文件的HTTP请求,该请求发送给服务器
4)服务器处理请求并返回HTTP报文:服务器对浏览器请求做出响应,把对应的带有HTML文本的HTTP响应报文发送给浏览器
5)浏览器解析渲染页面
6)连接结束:浏览器释放TCP连接,该步骤即四次挥手。第5步和第6步可以认为是同时发生的,哪一步在前没有特别的要求。
DNS域名解析流程
状态码由3位数字组成,第一位定义响应的类别
1XX:指示信息,服务器收到请求
2XX:请求成功,表示请求已经被成功接收、理解、接受
200 OK:正常返回信息
3XX:重定向,要完成请求必须进行进一步操作
301:永久重定向,配合location,浏览器自动处理。
302:临时重定向,配合location,浏览器自动处理。只是临时地从旧地址跳转到新地址
304:资源未被修改
4XX:客户端错误,请求由语法错误或请求无法实现
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。此时需要分析客户端的代码,去看看请求为什么出现服务 器无法理解的错误。
401 Unauthorized:缺失或错误的认证,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:客户端请求没有权限去访问要求的资源。
404 Not Found:请求资源不存在,检擦URL或路径配置。
5XX:服务端错误,服务器未能实现合法的请求
500 Internal Server Error:服务器错误。检查服务器日志,看看里面的代码哪里错误,进而抛出异常。
502 Bad Gateway:服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
504 Gateway Timeout:网关超时,由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。
method:
get 获取数据
post 新建数据
patch/put 更新数据
delete 删除数据
Restful API:
传统API设计:把每个url当作一个功能
- post请求: /api/create-blog
-
- /api/update-blog?id=100
-
- get请求:/api/get-blog?id=100
Restful API:把每个url当作一个唯一的资源
- post请求:/api/blog
-
- patch请求:/api/blog/100
-
- get请求:/api/blog/100
1)Http报文层面:GET将请求信息放在URL,POST放在报文体中。(GET请求信息与URL之间用?隔开,请求信息的格式为键值对。POST想获得请求信息必须解析报文。GET中的请求信息放在URL中,长度有限制,浏览器会对URL的长度做出限制。POST请求对数据长度没有限制)
2)数据库层面:GET符合幂等性和安全性,POST不符合。(幂等性:对数据库的一次操作和多次操作获得的结果是一致的。安全性:对数据库的操作没有改变数据库中的数据。GET操作是查询操作,不会改变数据库中原有的数据,大致认为符合安全性和幂等性。POST请求既不幂等也不安全,POST请求会往数据库中提交数据,会改变数据库中的数据;POST请求每次获得的结果都有可能不一样,因为POST作用在上一级的URL,每一次请求都会添加一份新资源)
3)其他层面:GET可以被缓存,被存储,而POST不行。GET请求被保存在浏览器的浏览记录中,GET请求的URL能保存为浏览器书签;POST方式不具备上述功能。缓存也是GET请求被广泛应用的根本,减少服务器的负担。
Content-Type最常见的几种类型:
application/x-www-form-urlencoded form表单默认的数据格式,提交的数据形式 key1=val1&key2=val2(参数少)
multiple/form-data 一般用来上传文件,也可以上传普通数据
application/json json对象(参数多)
post请求postman的几种参数格式区别:
form-data对应的是以form表单提交传值的情形,等价于http请求中的multipart/form-data
x-www-form-urlencoded即application/x-www-from-urlencoded,将表单内的数据转换为Key-Value;
raw对应的是入参是任意格式的可以上传任意格式的【文本】,可以上传text、json、xml、html等;
binary相当于Content-Type:application/octet-stream,只可以上传二进制数据,通常用来上传文件,但是一次只能上传一个文件
缓存减少网络请求数量和体积,使页面渲染更快。并且网络请求不稳定。
静态资源(js、css、img)可以被缓存
强缓存
直接从缓存中获取资源而不经过服务器;与强缓存相关的header字段:
Cache-Control max-age:最大过期时间;no-cache:不用强制缓存,向服务端请求,不管服务端怎么处理;no-store:不用强制缓存,不让服务端做缓存,让服务端简单粗暴的把资源返回。
Expires 已被Cache-Control代替
协商缓存
协商缓存由服务端来确定缓存资源是否可用,而不是缓存到服务端。服务器判断客户端资源是否和服务端资源一致,一致则返回304;否则返回200。
资源标识:
Last-Modified 资源的最后修改时间,再次请求If-Modified-Since
Etag 资源的唯一标识,再次请求 If-None-Match(优先)
完整流程图
三种刷新操作
正常操作:地址栏输入url,跳转链接,前进后退等
手动刷新:F5,点击刷新按钮,右击菜单刷新
强制刷新:ctrl+F5
正常刷新强制缓存有效,协商缓存有效
手动刷新强制缓存失效,协商缓存有效
强制刷新强制缓存失效,协商缓存失效
Cookie:
Cookie是客户端的解决方案,是由服务器发送给客户端的特殊信息,以文本的形式存放在客户端。客户端每次向服务器发送请求时,都会带上这些特殊的信息。具体些,当用户使用浏览器访问一个支持Cookie的网站时,用户会提供包括用户名在内的个人信息,并且提交至服务器。服务器在向客户端回传相应的超文本的同时,也会发回这些个人信息,这些信息存放在HTTP响应头。当浏览器接受到来自服务器的响应后,浏览器会将这些信息存在一个统一的位置。客户端再向服务器发送请求时,会把相应的Cookie再次发送至服务器中。这次Cookie信息存放在HTTP请求头里面。服务器接收到请求后,会解析存放于请求头的Cookie,得到客户端特有的信息,动态生成和客户端相对应的内容。
Cookie的设置和发送过程分以下4步:客户端发送一个HTTP请求到服务器端,服务端发送一个HTTP响应到客户端(包含Set-Cookie头部),客户端在发送一个HTTP请求到服务端(包含Cookie头部),服务器端发送一个HTTP响应到客户端。
Session:
服务器端的机制,服务器采用类似散列表的结构来保存信息。当程序需要为某个客户端请求创建一个Session的时候,服务器首先检查客户端的请求里是否包含Session的标识,称为Session id。如果包含Session id,则说明以前为此客户端创建过Session。服务器就按照这个Session id,把Session检索出来使用,检索不到会新建一个;如果客户端请求不包含Session id,则为此客户端创建一个Session,并请生成与此Seesion相关的Session id。Session id的值是一个既不会重复用不容易被找到规律的字符串。Session id在本次响应中回发给客户端进行保存。
Session的实现方式主要有两种:
1)使用Cookie来实现。服务器给每个Session分配一个唯一的JSession id,并通过Cookie发送给客户端。客户端发起新的请求的时候,将在Cookie头中携带的JSession id,服务器找到客户端对应的Session。
2)使用URL回写来实现。URL回写是指服务器在发送给浏览器页面的所有链接都携带JSession id的参数,客户端点击任何一个链接,都会把JSession id带回服务器,如果直接在浏览器输入服务端资源的URL来请求该资源,Session是匹配不到的。
Tomcat对Session的实现是一开始同时使用Cookie和URL回写机制,如果发现客户端支持Cookie,就继续使用Cookie,停止使用URL回写;如果发现Cookie被禁用,就一直使用URL回写。
Cookie和Session的区别:
1)Cookie数据存放在客户的浏览器上,Session数据放在服务器上。
2)Session相对Cookie更安全
3)Session会在一定时间保存在服务器上,考虑到服务器性能的开销,应到使用Cookie
单点登录
HTTPS超文本传输安全协议,以计算机网络安全通信为目的的传输协议。在HTTP协议下加入了SSL层,从而具有了保护交换数据隐私和完整性,提供对网上服务器身份认证的功能。简单来说就是安全版的HTTP。
SSL安全套接层,为网络通信提供安全及数据完整性的一种安全协议。位于TCP和各应用层之间,是操作系统对外的API,SSL3.0以后更名为TLS,采用身份验证和数据加密保证网络通信的安全和数据的完整性。
加密的方式(了解):
对称加密:加密和解密都使用同一个密钥。
非对称加密:加密使用的密钥和解密使用的密钥是不相同的,分为称为公钥和私钥。公钥算法公开,私钥保密。非对称加密算法性能较低,安全性强,能加密的数据长度有限。区块链很多都用到非对称加密。
哈希算法:将任意长度的信息转换为固定长度的值,算法不可逆。如MD5算法。
数字签名:证明某个信息或者文件是某人发出认同的。签名即在信息的后面加上一段内容,内容经过HashCode值可以证明信息没有被修改过。
HTTPS采用证书配合各种加密手段的方式。
HTTPS数据传输流程:
1)浏览器将支持的加密算法信息发送给服务器。
2)服务器选择一套浏览器支持的加密算法,将验证身份的信息以证书的形式回发浏览器。证书信息包含证书发布的CA机构、证书的有效期、公钥、证书所有者、签名等等。CA机构是具备证书颁发资格的机构。
3)浏览器收到证书后首先验证证书的合法性,如果证书受到浏览器信任则在浏览器地址栏会有标志显示,否则就会显示不授信的标识。证书授信后web浏览器会随机生成一串密码,并使用证书中的公钥加密,之后使用约定好的Hash算法握手消息并生成随机数对消息进行加密,在将之前生成的消息回发给服务器。
4)当服务器接收到浏览器发送过来的数据后,会使用私钥将信息解密确定密码,通过密码解密web浏览器发送过来的握手信息并验证hash是否与web浏览器一致,服务器会使用密码加密新的握手信息发送给浏览器。
5)客户端浏览器解密并计算经过Hash算法加密的消息,如果与服务器发送过来的hash值一致,则此握手过程结束后服务器和浏览器会使用之前浏览器生成的随机密码和对称加密算法进行加密然后交换数据。
HTTP和HTTPS区别:
1)HTTPS需要到CA申请证书(一般免费证书较少,需要一定的费用);HTTP不需要
2)HTTPS是具有安全性的SSL加密传输协议,密文传输;HTTP信息是明文传输的
3)链接方式不同。HTTPS默认使用443端口;HTTP使用80端口
4)HTTPS协议是由SSL+HTTP协议构建的可进行加密传输身份认证的网络协议,SSL是有状态的。HTTPS=HTTP+加密+认证+完整性保护,较HTTP安全;HTTP连接是无状态的
用户习惯访问网站时只输入一个域名,不会在域名前填充HTTP或HTTPS,浏览器默认填充http://,需要跳转到HTTPS。这个过程会使用到HTTP,有被劫持的风险,受到第三方的攻击。可以使用HSTS优化,HSTS目前正在推行中,没有成为主流,自己了解。
两个进程需要通信,需要唯一标识进程,在本地进程通信中,可以使用pid来唯一标识一个进程。但pid只在本地唯一,网络中的两个进程pid有可能冲突。
IP层的ip地址可以唯一标识一台主机,tcp协议和端口号可以唯一标识主机中的一个进程,IP地址+协议+端口号唯一标识网络中的一个进程。能够唯一标识网络中的进程后,他们就可以利用Socket进行通信。
Socket跟TCP/IP协议没有必然的联系,使程序员更方便的使用TCP/IP协议栈。Socket是对TCP/IP的抽象,从而形成了最基本的函数接口,如create、listen、connect、accept、send、read、write。Socket起源于UNIX,UINX准从一切皆文件的哲学,Socket是基于一种从打开到读和写再到关闭的模式去实现的。服务器和客户端各自维护一个文件,在建立连接打开后,可以向自己文件写入内容供对方读写或读写对方文件。
使用TCP协议通信的Socket为例,通信流程描述如下:
服务器先创建Socket,为Socket绑定IP地址和端口号,服务器的Socket会监听端口号的请求,随时准备接收客户端发来的连接,此时服务器的Socket只是Listen并没有打开。假设客户端创建了Socket,打开了Socket并根据服务器的IP地址和端口号尝试去连接服务器的 Socket。服务器的Socket接收到客户端的Socket请求被动的打开,开始接收客户端的请求直到客户端返回连接信息。此时服务器的Socket进入阻塞状态,阻塞即Accept方法需要一直等待客户端返回连接信息后才返回,同时开始接收下一个客户端的连接请求。客户端在连接成功后就会向服务器发送连接状态信息。服务器端在接收到客户端的连接信息之后就会将Accept方法返回并提示连接成功。之后客户端就可以向Socket写入信息,服务器就能收到并且读取相关的信息。最后在发送完数据后客户端就会关闭Socket,紧接着服务器也需要关闭Socket。
《图解HTTP》、《TCP/IP详解卷1》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。