TCP/IP常见问题总结(二)

上一篇文章的传送门:TCP/IP常见问题总结(一)

TCP滑动窗口与回退N帧协议

TCP作为一个提供可靠服务的传输层协议,对于数据的发送必须拥有一套良好的反馈机制,让发送方得知接收方接收到了数据,而TCP下的反馈机制大部分借鉴与数据链路层的反馈机制,因此在此我们分析一下数据链路层的反馈机制。

停等协议

停等协议是一种非常简单的协议,发送方在发送完一帧数据后就一直等待接收方的确认信号(ACK),要是超时就重传数据,只到收到ACK信号后才发送下一帧数据。停等协议效率较低(如此低效数据链路层都不适用,TCP协议当然也不用了),其示意图如下:
停等协议示意图

滑动窗口协议之GoBackN

由于发完一帧数据后发送方就挂起等待的行为非常低效,因此滑动窗口协议诞生了。滑动窗口的意思其实就是一个缓冲区(发送方为发送窗口,接收方为接收窗口),缓冲区的内容会随着数据的发送而移动,因此称为滑动窗口。
我们先来讲讲滑动窗口协议中的GoBackN协议。滑动窗口协议允许发送方连发数帧,每发一帧都对应 一个计时器timeout,而GoBackN协议要求发送方把丢失帧及其之后的帧全部重传(因为光凭一个ACK并不能确定哪些帧出现了丢失,ACK的含义是:期待接收序号为N的帧,之前所有的帧都已经成功收到并依此交给了上层)。其示意图如下:
滑动窗口协议之GoBackN示意图

上面的示意图由于Data2丢失,导致了Data2~Data5的重发(窗口大小为4)

滑动窗口协议之选择性重发

由于GoBackN中重发已经发送过的数据有点多余,因此选择性重发协议诞生了。选择性重发协议在ACK上引入了NAK的概念(否定性确认帧),表示小于N的帧已经全部收到并交给了上层,而第N帧丢失了,要求重发第N帧。当发送方接到NAK后,只要重发NAK表示的那一帧即可。其示意图如下:
滑动窗口协议之选择性重发示意图

上图中发送方发送的Data2丢失了,因此收到了接收方的NAK2,然后发送方只需重新发送Data2即可。
在TCP协议中使用的也是选择性重发协议。

Http的报文结构

Http协议(Hypertext Transfer Protocol)即超文本传输协议,它是一个应用层的基于TCP的无状态的协议,一般的通信过程为:建立连接、发送请求、响应请求、释放连接。其报文结构分为请求头与响应头两种:

请求头

http请求头示意图

请求头的第一行为请求行,其包括了三部分重要内容:

  1. 请求方法:主要为Get、Post等方法
  2. URL:即请求的地址
  3. 协议版本:主要有Http1.0和Http1.1两种

请求头接下来是请求头部(也叫头域),头域的长度是不固定的,每一个头域属性的格式为:字段名:值(如:Range:请求范围)
头域下面是一行空行,表示头域的结束。
空行下来就是请求要提交的数据。

响应头

http响应头示意图

与请求头类似,响应头的第一行为响应行,主要包含如下三部分内容:

  1. 版本:使用的Http协议版本
  2. 状态码:表示处理结果状态的数值,由三位数字组成,第一位数字表示响应的类型,主要有以下几种:
    • 1XX:表示服务器已接收了客户端请求,客户端可继续发送请求
    • 2XX:表示服务器已成功接收到请求并进行处理
    • 3XX:表示服务器要求客户端重定向
    • 4XX:表示客户端的请求有非法内容
    • 5XX:表示服务器未能正常处理客户端的请求而出现意外错误
  3. 原因短语:一串用于解释返回该状态码原因的字符串

响应行下来是响应头域,与请求头类似。
响应头域下来是一行空行表示响应头域的结束。
最后是响应头的响应实体内容。

Http的状态码含义

状态码位于响应头的响应行中,表示服务器处理结果的情况,由三位数字组成,第一位数字表示响应的类型,主要有以下几种:

1XX:表示服务器已接收了客户端请求,客户端可继续发送请求

100 (Continue/继续)
如果服务器收到头信息中带有100-continue的请求,这是指客户端询问是否可以在后续的请求中发送附件。在这种情况下,服务器用100允许客户端继续或用417 (Expectation Failed)告诉客户端不同意接受附件。这个状态码是 HTTP 1.1中新加入的。

101 (Switching Protocols/转换协议)
101 状态码是指服务器将按照其上的头信息变为一个不同的协议。这是 HTTP 1.1中新加入的。

2XX:表示服务器已成功接收到请求并进行处理

200 (OK/正常)
200 的意思是一切正常。一般用于相应GET和POST请求。

201 (Created/已创建)
201表示服务器在请求的响应中建立了新文档;应在定位头信息中给出它的URL。

202 (Accepted/接受)
202告诉客户端请求正在被执行,但还没有处理完。

203 (Non-Authoritative Information/非官方信息)
状态码203是表示文档被正常的返回,但是由于正在使用的是文档副本所以某些响应头信息可能不正确。这是 HTTP 1.1中新加入的。

204 (No Content/无内容)
在并没有新文档的情况下,204确保浏览器继续显示先前的文档。这各状态码对于用户周期性的重载某一页非常有用,并且你可以确定先前的页面是否已经更新。但是,这种方法对通过刷新响应头信息或等价的HTML标记自动重载的页面起作用,因为它会返回一个204状态码停止以后的重载。但基于JavaScript脚本的自动重载在这种情况下仍然需要能够起作用。

205 (Reset Content/重置内容)
重置内容205的意思是虽然没有新文档但浏览器要重置文档显示。这个状态码用于强迫浏览器清除表单域。这是 HTTP 1.1中新加入的。

206 (Partial Content/局部内容)
206是在服务器完成了一个包含Range头信息的局部请求时被发送的。这是 HTTP 1.1中新加入的。

3XX:表示服务器要求客户端重定向

300 (Multiple Choices/多重选择)
300表示被请求的文档可以在多个地方找到,并将在返回的文档中列出来。如果服务器有首选设置,首选项将会被列于定位响应头信息中。

301 (Moved Permanently)
301状态是指所请求的文档在别的地方;文档新的URL会在定位响应头信息中给出。浏览器会自动连接到新的URL。

302 (Found/找到)
与301有些类似,只是定位头信息中所给的URL应被理解为临时交换地址而不是永久的。注意:在 HTTP 1.0中,消息是临时移动(Moved Temporarily)的而不是被找到。

303 (See Other/参见其他信息)
这个状态码和 301、302 相似,只是如果最初的请求是 POST,那么新文档(在定位头信息中给出)药用 GET 找回。这个状态码是新加入 HTTP 1.1中的。

304 (Not Modified/为修正)
当客户端有一个缓存的文档,通过提供一个 If-Modified-Since 头信息可指出客户端只希望文档在指定日期之后有所修改时才会重载此文档,用这种方式可以进行有条件的请求。304是指缓冲的版本已经被更新并且客户端应刷新文档。另外,服务器将返回请求的文档及状态码 200。

305 (Use Proxy/使用代理)
305表示所请求的文档要通过定位头信息中的代理服务器获得。这个状态码是新加入 HTTP 1.1中的。

307 (Temporary Redirect/临时重定向)
浏览器处理307状态的规则与302相同。307状态被加入到 HTTP 1.1中是由于许多浏览器在收到302响应时即使是原始消息为POST的情况下仍然执行了错误的转向。只有在收到303响应时才假定浏览器会在POST请求时重定向。添加这个新的状态码的目的很明确:在响应为303时按照GET和POST请求转向;而在307响应时则按照GET请求转向而不是POST请求。该状态码是新加入HTTP 1.1中的。

4XX:表示客户端的请求有非法内容

400 (Bad Request/错误请求)
400指出客户端请求中的语法错误。

401 (Unauthorized/未授权)
401表示客户端在授权头信息中没有有效的身份信息时访问受到密码保护的页面。这个响应必须包含一个WWW-Authenticate的授权信息头。

403 (Forbidden/禁止)
403的意思是除非拥有授权否则服务器拒绝提供所请求的资源。这个状态经常会由于服务器上的损坏文件或目录许可而引起。

404 (Not Found/未找到)
404状态每个网络程序员可能都遇到过,他告诉客户端所给的地址无法找到任何资源。它是表示“没有所访问页面”的标准方式。

405 (Method Not Allowed/方法未允许)
405指出请求方法(GET, POST, HEAD, PUT, DELETE, 等)对某些特定的资源不允许使用。该状态码是新加入 HTTP 1.1中的。

406 (Not Acceptable/无法访问)
406表示请求资源的MIME类型与客户端中Accept头信息中指定的类型不一致。406是新加入 HTTP 1.1中的。

407 (Proxy Authentication Required/代理服务器认证要求)
407与401状态有些相似,只是这个状态用于代理服务器。该状态指出客户端必须通过代理服务器的认证。代理服务器返回一个Proxy-Authenticate响应头信息给客户端,这会引起客户端使用带有Proxy-Authorization请求的头信息重新连接。该状态码是新加入 HTTP 1.1中的。

408 (Request Timeout/请求超时)
408是指服务端等待客户端发送请求的时间过长。该状态码是新加入 HTTP 1.1中的。

409 (Conflict/冲突)
该状态通常与PUT请求一同使用,409状态常被用于试图上传版本不正确的文件时。该状态码是新加入 HTTP 1.1中的。

410 (Gone/已经不存在)
410告诉客户端所请求的文档已经不存在并且没有更新的地址。410状态不同于404,410是在指导文档已被移走的情况下使用,而404则用于未知原因的无法访问。该状态码是新加入 HTTP 1.1中的。

411 (Length Required/需要数据长度)
411表示服务器不能处理请求(假设为带有附件的POST请求),除非客户端发送Content-Length头信息指出发送给服务器的数据的大小。该状态是新加入 HTTP 1.1的。

412 (Precondition Failed/先决条件错误)
412状态指出请求头信息中的某些先决条件是错误的。该状态是新加入 HTTP 1.1的。

413 (Request Entity Too Large/请求实体过大)
413告诉客户端现在所请求的文档比服务器现在想要处理的要大。如果服务器认为能够过一段时间处理,则会包含一个Retry-After的响应头信息。该状态是新加入 HTTP 1.1的。

414 (Request URI Too Long/请求URI过长)
414状态用于在URI过长的情况时。这里所指的“URI”是指URL中主机、域名及端口号之后的内容。该状态是新加入 HTTP 1.1的。

415 (Unsupported Media Type/不支持的媒体格式)
415意味着请求所带的附件的格式类型服务器不知道如何处理。该状态是新加入 HTTP 1.1的。

416 (Requested Range Not Satisfiable/请求范围无法满足)
416表示客户端包含了一个服务器无法满足的Range头信息的请求。该状态是新加入 HTTP 1.1的。

417 (Expectation Failed/期望失败)
如果服务器得到一个带有100-continue值的Expect请求头信息,这是指客户端正在询问是否可以在后面的请求中发送附件。在这种情况下,服务器也会用该状态(417)告诉浏览器服务器不接收该附件或用100状态告诉客户端可以继续发送附件。该状态是新加入 HTTP 1.1的。

5XX:表示服务器未能正常处理客户端的请求而出现意外错误

500 (Internal Server Error/内部服务器错误)
500是常用的“服务器错误”状态。

501 (Not Implemented/未实现)
501状态告诉客户端服务器不支持请求中要求的功能。例如,客户端执行了如PUT这样的服务器并不支持的命令。

502 (Bad Gateway/错误的网关)
502被用于充当代理或网关的服务器;该状态指出接收服务器接收到远端服务器的错误响应。

503 (Service Unavailable/服务无法获得)
状态码503表示服务器由于在维护或已经超载而无法响应。

504 (Gateway Timeout/网关超时)
该状态也用于充当代理或网关的服务器;它指出接收服务器没有从远端服务器得到及时的响应。该状态是新加入 HTTP 1.1的。

505 (HTTP Version Not Supported/不支持的 HTTP 版本)
505状态码是说服务器并不支持在请求中所标明 HTTP 版本。该状态是新加入 HTTP 1.1的。

Http request的几种方法

在Http中主要包含以下请求方法:

  • GET: 请求指定的页面信息,并返回实体主体
  • HEAD: 只请求页面的首部。
  • POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体
  • PUT: 从客户端向服务器传送的数据取代指定的文档的内容
  • DELETE: 请求服务器删除指定的页面
  • OPTIONS: 允许客户端查看服务器的性能
  • TRACE: 请求服务器在响应中的实体主体部分返回所得到的内容
  • PATCH: 实体中包含一个表,表中说明与该URI所表示的原内容的区别
  • MOVE: 请求服务器将指定的页面移至另一个网络地址
  • COPY: 请求服务器将指定的页面拷贝至另一个网络地址
  • LINK: 请求服务器建立链接关系
  • UNLINK: 断开链接关系
  • WRAPPED: 允许客户端发送经过封装的请求
  • CONNECT:用于动态切换到隧道的代理

其中Http1.0仅支持GET、HEAD和POST,其余方法均为Http1.1添加。
值的注意的是:GET方法与POST方法类似,但GET方法参数写在URL上,POST参数写在请求实体内容中,且GET方法参数不大于1024Byte,POST则没有限制。

Http1.1和Http1.0的区别

Http1.0与Http1.1主要有以下区别:

  1. 是否允许复用连接:Http1.0不允许,响应请求后就断开连接,Http1.1允许且默认开启连接复用
  2. Host头域:Http1.0没有,Http1.1有
  3. 状态码:Http1.1比Http1.0多了100,101,203,205等状态码
  4. 请求方式:Http1.0只有GET、HEAD和POST方法,Http1.1新增了其他多种方法