计算机网络面试查漏补缺

190 阅读9分钟

OSI七层协议

应用层

应用程序, 产生数据, 利用网络形成应用

  • DNS域名系统
  • HTTP超文本传输协议
  • SMTP邮件协议
  • ...

表示层

负责信息语法语义, 如加解密, 转换, 压缩解压缩

会话层

负责不同机器上用户之间建立和管理会话

TCP实际上实现了这部分功能, 使用一张表存储所有TCB(transmission control block), 来确定每个TCP包属于那个session

TCB除了双方的IP,port,应答序号,还记录了双方的窗口大小,队列,重传等变量

传输层

负责两台主机进程间的数据传输服务(端口号), 将数据分割,交给下一层

  • TCP 流传输, 数据分包
  • UDP 报文

网络层

两台计算机之间数据传输-数据报, 负责选择合适的网间路由(router)和交换节点.

数据链路层

负责物理寻址, 数据传输实际上是在一段一段的链路上进行, 相邻节点之间, 需要间IP数据报组装为帧, 每个帧包含数据和控制信息

物理层

数据单位为bit, 屏蔽传输介质和物理设备的差异

输入URL到显示页面的过程

  1. DNS解析
  2. TCP连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. TCP连接结束

TCP UDP

TCPUDP
连接有连接无连接
方向双向单向
传输字节流报文
数据边界×
可靠性×
有序性×
系统资源
首部字节20-60 1500-20IP头-20+TCP头8 1500-20IP头-4UDP头 标准MTU=576-20-8

三次握手

--SYN m--> <--SYNn/ACKm+1-- --ACKn+1-->

SYN是握手信号, 向对方发送自己的序列化; ACK是确认信号; m,n为随机数

若服务端发送SYN/ACK后没有收到客户端响应, 会重发, 如果仍然没有响应, 不创建连接. linux中重试5次, 时间间隔为1s, 2s, 4s, 8s, 16s,总共31s, 最后再等待32s

为什么不能两次握手

如果发送方的第一次SYN请求受到网络延迟, 发送方可能重发SYN建立连接. 如果第一次的SYN在连接结束后到达接收方, 则错误地使接收方以为是新的连接请求

四次挥手

--FIN--> <--ACK-- <--FIN-- --ACK-->

接收方发送第二步的ACK后, 可能还有数据要发送, 可以继续发送

接收方收到第四步的ACK即可关闭连接

发送方发完ACK后等待一段时间后才连接关闭

TCP如何保证可靠性

  1. 数据分包(避免IP分片, 1460+20TCP头+20IP头字节)
  2. 包编号
  3. 校验和(首部和数据的检验和)
  4. 流量控制(滑动窗口:滑动窗口大小=接收方缓冲区剩余大小, 除紧急数据)
  5. 拥塞控制(拥塞窗口;慢开始,拥塞避免,快重传(收到3个重复确认后立即重传),快恢复)
  6. 停止等待协议(连续ARQ,发送窗口+累积确认, 缺点Go-back-N)
  7. 超时重传(定时器动态翻倍防止拒绝服务攻击)
  8. 选择确认(可以确认成功收到的不连续块,避免大量重传. 默认累计确认)

滑动窗口

发送方滑动窗口:

TCP发送窗口

接收方告知发送方自己的窗口大小, 控制发送窗口的大小

TCP 长连接短连接

短连接: 通过正常的握手建立连接, 只传输一次数据, 四次挥手关闭连接

长连接: 不关闭连接, 由服务端提供保活功能. 超过2个小时无响应, 服务端向客户端发送探测报文段(客户端正常响应则服务端将保活计数器复位;客户端无响应则服务器每隔75s发送一个探测, 若均为反应服务端关闭连接)

HTTP协议

HTTP协议无状态, 即对事务处理没有记忆能力

HTTP请求报文

<method> <URL> HTTP/1.1
<host>
<headers>

<content>

GET请求示例

GET /books/?sex=man&name=Professional HTTP/1.1
 Host: www.example.com
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1
 Connection: Keep-Alive
 If-Modified-Since:Thu, 4 Feb 2010 20:39:13 GMT  
 Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW &lt; HttpOnly

POST请求示例

POST /books/addbook HTTP/1.1
 Host: www.olive.com:8080
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1
 Connection: Keep-Alive
 Content-type: application/x-www-form-urlencoded
 Content-length: 40
 
 sex=man&name=Professional  

x-www-form-urlencoded即与GET相同的内容格式, 用来传输<form>表单的内容. 但POST请求的内容不会被保存到标签或输出到日志, 且没有长度要求

multipart/form-data如果为<form>表单设置enctype = multipart/form-data, 则会以下面方式传输

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

application/json, text/xml也是常用的格式

HTTP响应报文

HTTP/1.1 200 OK

Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
Set-Cookie: sid=1342077140226724; path=/; expires=Wed,10-Oct-12 07:12:20 GMT; HttpOnly

<html>...

Set-CookieHttpOnly属性表示JavaScript的document.cookie无法获取cookie

常见的响应状态还有:

301Moved Permanently
302Moved Temporarily
304Not Modified
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error
503Service Unavailable

HTTP Keep-Alive

HTTP1.0需设置Connection:Keep-Alive, 服务端收到请求后也在响应中添加同样的字段, 则该HTTP连接是长连接(借助TCP的长连接)

HTTP1.1版本默认情况下所有连接都被保持,加入Connection: close才关闭

Keep-Alive: timeout=5, max=100
//表示这个TCP通道可以保持5秒,max=100表示这个长连接最多接收100次请求就断开

HTTP是无连接无状态的, 实际是使用TCP的长连接.

HTTP因此需要一个东西标识长连接结束. 有以下两种方式:

  1. Content-Length

    表示总传输长度, 需要传完所有内容断开连接

  2. Transfer-Encoding:chunk

    动态页面服务是不可能预先知道内容大小, 即如果要一边产生数据,一边发给客户端,服务器就需要使用Transfer-Encoding: chunked. chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束

会话追踪

指对同一个用户对服务器的连续的请求和接受响应的监视. HTTP无状态, 用会话追踪保存用户状态.

  1. URL重写

    URL(统一资源定位符)是Web上特定页面的地址,URL重写的技术就是在URL结尾添加一个附加数据以标识该会话,把会话ID通过URL的信息传递过去,以便在服务器端进行识别不同的用户。

  2. 隐藏表单域

    将会话ID添加到HTML表单元素中提交到服务器,此表单元素并不在客户端显示

  3. Cookie

    Cookie 是Web服务器发送给客户端的一小段信息,客户端请求时可以读取该信息发送到服务器端,进而进行用户的识别。对于客户端的每次请求,服务器都会将 Cookie 发送到客户端,在客户端可以进行保存,以便下次使用。

    客户端可以采用两种方式来保存这个 Cookie 对象,一种方式是保存在客户端内存中,称为临时 Cookie,浏览器关闭后这个 Cookie 对象将消失。另外一种方式是保存在客户机的磁盘上,称为永久 Cookie。以后客户端只要访问该网站,就会将这个 Cookie 再次发送到服务器上,前提是这个 Cookie 在有效期内

    Cookie 是可以被客户端禁用的。

  4. Session:

    在服务器端会创建一个 session 对象,产生一个 sessionID 来标识这个 session 对象,然后将这个 sessionID 放入到 Cookie 中发送到客户端,或如果cookie被禁用, 可用前两种方式

客户端禁用cookie如何实现session

  • 设置php.ini配置文件中的“session.use_trans_sid = 1”,或者编译时打开打开了“--enable-trans-sid”选项,让PHP自动跨页传递Session ID。

  • 手动通过URL传值、隐藏表单传递Session ID。

  • 用文件、数据库等形式保存Session ID,在跨页过程中手动调用。

CSRF(Cross-site request forgery 跨站请求伪造)

在页面上放一个链接, 引诱用户点击, 则用户会不知晓地发送GET请求

解决方案:

  1. 改用POST请求
  2. Token验证(随机)
  3. 验证码
  4. 检测Referer(用户点击网页上的链接;发送表单;网页加载静态资源时请求headers中有Referer字段)

XSS(Cross Site Scripting 跨站脚本攻击)

在输入中加入javascript代码, 执行

  1. HTML excape

    对特殊字符替换, 使之显示为正常内容

  2. HTML解析库

    需要用户输入html标签时, 将用户的输入进行解析,获取其中的数据。然后根据用户原有的标签属性,重新构建HTML元素树。构建的过程中,所有的标签、属性都只从白名单中拿取

SQL注入

  • PreparedStatement(简单又有效的方法)

  • 使用正则表达式过滤传入的参数

  • 字符串过滤

  • JSP中调用该函数检查是否包函非法字符

  • JSP页面判断代码

HTTP1.0 vs 1.1

  1. 默认长连接
  2. 增加24个错误状态响应码
  3. 缓存处理, headers中加入了更多缓存控制策略
  4. 带宽优化, 加入range域, 返回码206表示partial

HTTP2.0

  1. 将原本的消息封装为frame
  2. 多路复用, 一个request对应一个stream并分配一个id,这样一个连接上可以有多个stream
  3. header压缩
  4. 流量控制, flow control(类似receive window)
  5. 服务端推送(server push)