UP打算把最近面试中被问到的一些关于计算机网络的问题进行了整理和总结,一方面方便自己复习,另一方面也希望帮助其他找工作找实习的同学。
应用层是网络体系中最高的一层,也是唯一面向用户的一层。这一层为用户的应用程序提供网络服务。
主要负责数据格式的转换,确保一个系统的应用层发送的消息可以被另一个系统的应用层读取,同时也对应用层的协议进行翻译。
负责网络中两节点的建立,在数据传输中维护计算机网络中两台计算机之间的通信连接,并决定何时终止通信。
定义了一些传输数据的协议(如:TCP、UDP)和端口号, 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。
负责帮助位于不同地理位置的网络中的两个主机系统之间提供连接和路径选择。
定义了如何让格式化数据在链路上进行传输,以及如何控制对物理介质的访问,在不可靠的物理介质上提供可靠的传输。
七层模型中的最底层,主要是物理介质传输媒介,在不同设备中传输比特流。
1、TCP面向连接(建立连接时需要三次握手,断开连接时需要四次挥手);UDP是无连接的,即发送数据之前不需要建立连接。
2、TCP提供可靠的服务,通过校验和、流量控制、超时重传机制、序列号、滑动窗口机制、确认应答机制(ACK)、拥塞控制实现可靠传输。UDP尽最大努力交付,即不保证可靠交付。
3、TCP对系统资源要求较多,UDP对系统资源要求较少。
4、TCP连接是点到点的;UDP支持一对一,一对多,多对一和多对多。
Seq:Seq是序号,占 4 字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号。TCP 是面向字节流的,通过 TCP 传送的字节流中的每个字节都按顺序编号,而报头中的序号字段值则指的是本报文段数据的第一个字节的序号。
ack:ack是确认号,占 4 字节,期望收到对方下个报文段的第一个数据字节的序号。
确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效。
同步SYN:连接建立时用于同步序号。
终止FIN:用来释放一个连接。
第一次握手:首先客户端向服务器端发送一段TCP报文,其中:标记位为SYN,表示“请求建立新连接”;序号为Seq=X。随后客户端进入SYN-SENT阶段。
第二次握手:服务器端接收到来自客户端的TCP报文之后发送一段TCP报文,标志位为SYN和ACK,表示确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接。序号为Seq=y,确认号为ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号ack的值;随后服务器端进入SYN-RCVD阶段。
第三次握手:客户端接收到来自服务器端的确认收到数据的TCP报文之后,返回TCP报文。其中:标志位ACK=1,表示确认收到服务器端同意连接的信号。序号为Seq=x+1,表示收到服务器端的确认号ack,并将其值作为自己的序号值;确认号为ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号ack的值;随后客户端进入ESTABLISHED阶段。
第一次挥手:客户端发送一个FIN=1,其序列号为seq=u,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。表示客户端没有数据要发给服务端了,但是如果服务器端还有数据没有发送完成,则不必关闭连接,可以继续发送数据。
第二次挥手:服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。服务端进入CLOSE_WAIT状态。
第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=1,ack=u+1报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,ACK=1,ack=w+1,自己的序列号是seq=u+1,接着进入TIME_WAIT状态。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭。最终完成了四次握手。
当关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭连接,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到服务端所有的报文都发送完了,才能发送FIN报文给客户端。因此需要四步握手。
TIME_WAIT状态用来重发可能丢失的ACK报文。在客户发送出最后的ACK回复,但该ACK可能会丢失。服务端如果没有收到ACK,将不断重复发送FIN片段。所以客户端不能立即关闭,它必须确认服务端接收到了该ACK。2MSL是两倍的MSL(Maximum Segment Lifetime,windows是两分钟,linux是30s)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,客户端都没有再次收到FIN,那么结束TCP连接。除此之外还可以保证了老的重复分节在网络中消逝 。
200 OK:表示从客户端发送给服务器的请求被正常处理并返回。
204 No Content:表示客户端发送给客户端的请求得到了成功处理。
301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL。
302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL。
303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源。与302的区别是303明确表示客户端应当采用GET方式获取资源。
400 Bad Request:表示请求报文中存在语法错误。
401 Unauthorized:未经许可,需要通过HTTP认证。
403 Forbidden:服务器拒绝该次访问。
404 Not Found:表示服务器上无法找到请求的资源。
500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时。
503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求。
在HTTP/1.0中,默认使用的是短连接。即浏览器和服务器每进行一次HTTP操作,就会建立一次连接,任务结束就断开连接。
在HTTP/1.1起,默认使用长连接。用以保持连接特性。使用长连接的情况下,当某个网页打开完毕之后,客户端和服务器之间的TCP连接不会关闭,如果客户端再次访问该服务器上的网页,会使用上一次已经建立的连接。长连接不是永久保持连接,它有一个保持时间。
长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive。在HTTP1.0中默认是使用短连接的,也就是说每一次请求都要建立起一次连接。
缓存处理:在HTTP1.0中主要使用了If-Modified-Since 和 Expires,而在http1.1中出现了跟多的缓存控制策略,例如Entity-tag、If-Unmodified-Since、If-Match、If-None-Match。
带宽优化以及网络连接的使用:在1.0中,存在着一些带宽浪费,譬如,一些用户只想请求某个对象的一部分内容,而服务器却将整个内容都发送了过来,并且不支持断点续传功能,而1.1在请求头部引入了range头,它允许请求资源的某个部分,返回码为206(Partial Content),此种做法方便了开发者调试以及合理的利用带宽资源。
错误状态响应码,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
浏览器首先会看自己缓存中有没有对应的ip地址,如果有的话就直接去访问;如果没有 浏览器会去查看本地的hosts文件,看看有没有和这个URL对应的ip地址,如果有的话就直接用, 如果本地的hosts 文件没有能够找到对应的 ip 地址,浏览器会发出一个 DNS请求到本地DNS服务器 ,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果。如果没有,本地DNS服务器还要向DNS根服务器进行查询。根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址 域服务器最终会返回给本地的DNS服务器一个具体的ip地址;然后本地的DNS服务器把这个具体的ip地址返回给浏览器,并且他自己也会把这个url请求对应的ip保存在自己本地。
浏览器通过DNS解析得到了服务器的IP地址后,与服务器建立TCP连接。三次握手连接:浏览器所在的客户机向服务器发出连接请求报文;服务器接收报文后,同意建立连接,向客户机发出确认报文;客户机接收到确认报文后,再次向服务器发出报文,确认已接收到确认报文;此处客户机与服务器之间的TCP连接建立完成,开始通信。
浏览器根据相应的机制对数据进行渲染,并展示页面。
Cookie简单来说是访问某些网站后在本地浏览器存储的一些网站相关信息,下次访问时减少一些步骤。比如我们在网页上登录某个账号时输入用户名及密码时如果保存为cookie,那么每次我们再访问的时候就不需要登录网站了。
Session是一种服务器端的机制,服务器使用一种类似HashTable的结构来保存信息。当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session id,如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用,如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id可以使用cookie返回给客户端。每次访问的时候将Session id带过去就可以识别了。