刨根问底HTTP和WebSocket协议美洲杯赌球

2019-04-16 20:11 来源:未知

刨根问底HTTP和WebSocket协议

2016/08/17 · 基础技术 · 1 评论 · HTTP, websocket

原文出处: TheAlchemist   

美洲杯赌球 1

那天和boss聊天,不经意间提到了Meteor,然后聊到了WebSocket,然后就有了以下对话,不得不说,看问题的方式不同,看到的东西也会大不相同。
A:Meteor是一个很新的开发框架,我觉得它设计得十分巧妙。
B:怎么个巧妙之处?
A:它的前后端全部使用JS,做到了真正的前后端统一;前端浏览器里存有一份后台开放出来的数据库的拷贝,快;使用WebSocket协议来做数据传输协议,来同步前后端的数据库,实现了真正的实时同步。
B:哦?WebSocket是什么东西?真实时?那底层是不是还是轮训?和HTTP的长连接有什么不同?
A:(开始心虚)它是一个新的基于TCP的应用层协议,只需要一次连接,以后的数据不需要重新建立连接,可以直接发送,它是基于TCP的,属于和HTTP相同的地位(呃,开始胡诌了),底层不是轮训,和长连接的区别……这个就不清楚了。
B:它的传输过程大致是什么样子的呢?
A:首先握手连接(又是胡诌),好像可以基于HTTP建立连接(之前用过Socket.io,即兴胡诌),建立了连接之后就可以传输数据了,还包括断掉之后重连等机制。
B:看起来和HTTP长连接做的事情差不多嘛,好像就是一种基于HTTP和Socket的协议啊。
A:呃……(我还是回去看看书吧)

有时候看事情确实太流于表面,了解到了每个事物的大致轮廓,但不求甚解,和朋友聊天说出来也鲜有人会刨根问底,导致了很多基础知识并不牢靠,于是回来大致把HTTP和WebSocket协议的RFC文档(RFC2616RFC6455),刚好对HTTP的传输过程一直有点模糊,这里把两个协议的异同总结一下。

WebSocket

只从RFC发布的时间看来,WebSocket要晚近很多,HTTP 1.1是1999年,WebSocket则是12年之后了。WebSocket协议的开篇就说,本协议的目的是为了解决基于浏览器的程序需要拉取资源时必须发起多个HTTP请求和长时间的轮训的问题……而创建的。

返回码

返回码是一个3位数,第一位定义的返回码的类别,总共有5个类别,它们是:

JavaScript

- 1xx: Informational - Request received, continuing process - 2xx: Success - The action was successfully received, understood, and accepted

  • 3xx: Redirection - Further action must be taken in order to complete the request - 4xx: Client Error - The request contains bad syntax or cannot be fulfilled - 5xx: Server Error - The server failed to fulfill an apparently valid request
1
2
3
4
5
6
7
8
9
10
11
12
13
  - 1xx: Informational - Request received, continuing process
 
  - 2xx: Success - The action was successfully received,
    understood, and accepted
 
  - 3xx: Redirection - Further action must be taken in order to
    complete the request
 
  - 4xx: Client Error - The request contains bad syntax or cannot
    be fulfilled
 
  - 5xx: Server Error - The server failed to fulfill an apparently
    valid request

RFC2616中接着又给出了一系列返回码的扩展,这些都是我们平时会用到的,但是那些只是示例,HTTP1.1不强制通信各方遵守这些扩展的返回码,通信各方在返回码的实现上只需要遵守以上边定义的这5种类别的定义,意思就是,返回码的第一位要严格按照文档中所述的来,其他的随便定义。

任何人接收到一个不认识的返回码xyz,都可以把它当做x00来对待。对于不认识的返回码的响应消息,不可以缓存。

HTTP

美洲杯赌球,HTTP的地址格式如下:

JavaScript

http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] 协议和host不分大小写

1
2
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
协议和host不分大小写
消息体(Message Body)和实体主体(Entity Body)

如果有Transfer-Encoding头,那么消息体解码完了就是实体主体,如果没有Transfer-Encoding头,消息体就是实体主体。

JavaScript

message-body = entity-body | <entity-body encoded as per Transfer-Encoding>

1
2
   message-body = entity-body
                | <entity-body encoded as per Transfer-Encoding>

在request消息中,消息头中含有Content-Length或者Transfer-Encoding,标识会有一个消息体跟在后边。如果请求的方法不应该含有消息体(如OPTION),那么request消息一定不能含有消息体,即使客户端发送过去,服务器也不会读取消息体。

在response消息中,是否存在消息体由请求方法和返回码来共同决定。像1xx,204,304不会带有消息体。

Response消息

响应消息跟请求消息几乎一模一样,定义如下:

JavaScript

Response = Status-Line *(( general-header | response-header | entity-header ) CRLF) CRLF [ message-body ]

1
2
3
4
5
6
   Response      = Status-Line              
                   *(( general-header        
                    | response-header      
                    | entity-header ) CRLF)  
                   CRLF
                   [ message-body ]

可以看到,除了header不使用request-header之外,只有第一行不同,响应消息的第一行是状态行,其中就包含大名鼎鼎的返回码

Status-Line的内容首先是协议的版本号,然后跟着返回码,最后是解释的内容,它们之间各有一个空格分隔,行的末尾以一个回车换行符作为结束。定义如下:

JavaScript

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

1
   Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
Response消息

响应消息跟请求消息几乎一模一样,定义如下:

JavaScript

Response = Status-Line *(( general-header | response-header | entity-header ) CRLF) CRLF [ message-body ]

1
2
3
4
5
6
   Response      = Status-Line              
                   *(( general-header        
                    | response-header      
                    | entity-header ) CRLF)  
                   CRLF
                   [ message-body ]

可以看到,除了header不使用request-header之外,只有第一行不同,响应消息的第一行是状态行,其中就包含大名鼎鼎的返回码

Status-Line的内容首先是协议的版本号,然后跟着返回码,最后是解释的内容,它们之间各有一个空格分隔,行的末尾以一个回车换行符作为结束。定义如下:

JavaScript

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

1
   Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

那天和boss聊天,不经意间提到了Meteor,然后聊到了WebSocket,然后就有了以下对话,不得不说,看问题的方式不同,看到的东西也会大不相同。
A:Meteor是一个很新的开发框架,我觉得它设计得十分巧妙。
B:怎么个巧妙之处?
A:它的前后端全部使用JS,做到了真正的前后端统一;前端浏览器里存有一份后台开放出来的数据库的拷贝,快;使用WebSocket协议来做数据传输协议,来同步前后端的数据库,实现了真正的实时同步。
B:哦?WebSocket是什么东西?真实时?那底层是不是还是轮训?和HTTP的长连接有什么不同?
A:(开始心虚)它是一个新的基于TCP的应用层协议,只需要一次连接,以后的数据不需要重新建立连接,可以直接发送,它是基于TCP的,属于和HTTP相同的地位(呃,开始胡诌了),底层不是轮训,和长连接的区别……这个就不清楚了。
B:它的传输过程大致是什么样子的呢?
A:首先握手连接(又是胡诌),好像可以基于HTTP建立连接(之前用过Socket.io,即兴胡诌),建立了连接之后就可以传输数据了,还包括断掉之后重连等机制。
B:看起来和HTTP长连接做的事情差不多嘛,好像就是一种基于HTTP和Socket的协议啊。
A:呃……(我还是回去看看书吧)

WebSocket

只从RFC发布的时间看来,WebSocket要晚近很多,HTTP 1.1是1999年,WebSocket则是12年之后了。WebSocket协议的开篇就说,本协议的目的是为了解决基于浏览器的程序需要拉取资源时必须发起多个HTTP请求和长时间的轮训的问题……而创建的。

Header

RFC2616中定义了4种header类型,在通信各方都认可的情况下,请求头可以被扩展的(可信的扩展只能等到协议的版本更新),如果接收者收到了一个不认识的请求头,这个头将会被当做实体头。4种头类型如下:

  1. 通用头(General Header Fields):可用于request,也可用于response的头,但不可作为实体头,只能作为消息的头。
JavaScript

general-header = Cache-Control ; Section 14.9 | Connection ; Section
14.10 | Date ; Section 14.18 | Pragma ; Section 14.32 | Trailer ;
Section 14.40 | Transfer-Encoding ; Section 14.41 | Upgrade ;
Section 14.42 | Via ; Section 14.45 | Warning ; Section 14.46

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977993ed3337597547-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed3337597547-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed3337597547-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed3337597547-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed3337597547-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed3337597547-6">
6
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed3337597547-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed3337597547-8">
8
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed3337597547-9">
9
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977993ed3337597547-1" class="crayon-line">
general-header = Cache-Control            ; Section 14.9
</div>
<div id="crayon-5a72977993ed3337597547-2" class="crayon-line crayon-striped-line">
              | Connection               ; Section 14.10
</div>
<div id="crayon-5a72977993ed3337597547-3" class="crayon-line">
              | Date                     ; Section 14.18
</div>
<div id="crayon-5a72977993ed3337597547-4" class="crayon-line crayon-striped-line">
              | Pragma                   ; Section 14.32
</div>
<div id="crayon-5a72977993ed3337597547-5" class="crayon-line">
              | Trailer                  ; Section 14.40
</div>
<div id="crayon-5a72977993ed3337597547-6" class="crayon-line crayon-striped-line">
              | Transfer-Encoding        ; Section 14.41
</div>
<div id="crayon-5a72977993ed3337597547-7" class="crayon-line">
              | Upgrade                  ; Section 14.42
</div>
<div id="crayon-5a72977993ed3337597547-8" class="crayon-line crayon-striped-line">
              | Via                      ; Section 14.45
</div>
<div id="crayon-5a72977993ed3337597547-9" class="crayon-line">
              | Warning                  ; Section 14.46
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 请求头(Request Header Fields):被请求发起端用来改变请求行为的头。
JavaScript

request-header = Accept ; Section 14.1 | Accept-Charset ; Section
14.2 | Accept-Encoding ; Section 14.3 | Accept-Language ; Section
14.4 | Authorization ; Section 14.8 | Expect ; Section 14.20 | From
; Section 14.22 | Host ; Section 14.23 | If-Match ; Section 14.24 |
If-Modified-Since ; Section 14.25 | If-None-Match ; Section 14.26 |
If-Range ; Section 14.27 | If-Unmodified-Since ; Section 14.28 |
Max-Forwards ; Section 14.31 | Proxy-Authorization ; Section 14.34 |
Range ; Section 14.35 | Referer ; Section 14.36 | TE ; Section 14.39
| User-Agent ; Section 14.43

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-6">
6
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-8">
8
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-10">
10
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-12">
12
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-13">
13
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-14">
14
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-15">
15
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-16">
16
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-17">
17
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ed9898424822-18">
18
</div>
<div class="crayon-num" data-line="crayon-5a72977993ed9898424822-19">
19
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977993ed9898424822-1" class="crayon-line">
request-header = Accept                   ; Section 14.1
</div>
<div id="crayon-5a72977993ed9898424822-2" class="crayon-line crayon-striped-line">
               | Accept-Charset           ; Section 14.2
</div>
<div id="crayon-5a72977993ed9898424822-3" class="crayon-line">
               | Accept-Encoding          ; Section 14.3
</div>
<div id="crayon-5a72977993ed9898424822-4" class="crayon-line crayon-striped-line">
               | Accept-Language          ; Section 14.4
</div>
<div id="crayon-5a72977993ed9898424822-5" class="crayon-line">
               | Authorization            ; Section 14.8
</div>
<div id="crayon-5a72977993ed9898424822-6" class="crayon-line crayon-striped-line">
               | Expect                   ; Section 14.20
</div>
<div id="crayon-5a72977993ed9898424822-7" class="crayon-line">
               | From                     ; Section 14.22
</div>
<div id="crayon-5a72977993ed9898424822-8" class="crayon-line crayon-striped-line">
               | Host                     ; Section 14.23
</div>
<div id="crayon-5a72977993ed9898424822-9" class="crayon-line">
               | If-Match                 ; Section 14.24
</div>
<div id="crayon-5a72977993ed9898424822-10" class="crayon-line crayon-striped-line">
               | If-Modified-Since        ; Section 14.25
</div>
<div id="crayon-5a72977993ed9898424822-11" class="crayon-line">
               | If-None-Match            ; Section 14.26
</div>
<div id="crayon-5a72977993ed9898424822-12" class="crayon-line crayon-striped-line">
               | If-Range                 ; Section 14.27
</div>
<div id="crayon-5a72977993ed9898424822-13" class="crayon-line">
               | If-Unmodified-Since      ; Section 14.28
</div>
<div id="crayon-5a72977993ed9898424822-14" class="crayon-line crayon-striped-line">
               | Max-Forwards             ; Section 14.31
</div>
<div id="crayon-5a72977993ed9898424822-15" class="crayon-line">
               | Proxy-Authorization      ; Section 14.34
</div>
<div id="crayon-5a72977993ed9898424822-16" class="crayon-line crayon-striped-line">
               | Range                    ; Section 14.35
</div>
<div id="crayon-5a72977993ed9898424822-17" class="crayon-line">
               | Referer                  ; Section 14.36
</div>
<div id="crayon-5a72977993ed9898424822-18" class="crayon-line crayon-striped-line">
               | TE                       ; Section 14.39
</div>
<div id="crayon-5a72977993ed9898424822-19" class="crayon-line">
               | User-Agent               ; Section 14.43
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 响应头(Response Header Fields):被服务器用来对资源进行进一步的说明。
JavaScript

response-header = Accept-Ranges ; Section 14.5 | Age ; Section 14.6
| ETag ; Section 14.19 | Location ; Section 14.30 |
Proxy-Authenticate ; Section 14.33 | Retry-After ; Section 14.37 |
Server ; Section 14.38 | Vary ; Section 14.44 | WWW-Authenticate ;
Section 14.47

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977993edd430163106-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993edd430163106-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977993edd430163106-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993edd430163106-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977993edd430163106-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993edd430163106-6">
6
</div>
<div class="crayon-num" data-line="crayon-5a72977993edd430163106-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993edd430163106-8">
8
</div>
<div class="crayon-num" data-line="crayon-5a72977993edd430163106-9">
9
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977993edd430163106-1" class="crayon-line">
response-header = Accept-Ranges           ; Section 14.5
</div>
<div id="crayon-5a72977993edd430163106-2" class="crayon-line crayon-striped-line">
                | Age                     ; Section 14.6
</div>
<div id="crayon-5a72977993edd430163106-3" class="crayon-line">
                | ETag                    ; Section 14.19
</div>
<div id="crayon-5a72977993edd430163106-4" class="crayon-line crayon-striped-line">
                | Location                ; Section 14.30
</div>
<div id="crayon-5a72977993edd430163106-5" class="crayon-line">
                | Proxy-Authenticate      ; Section 14.33
</div>
<div id="crayon-5a72977993edd430163106-6" class="crayon-line crayon-striped-line">
                | Retry-After             ; Section 14.37
</div>
<div id="crayon-5a72977993edd430163106-7" class="crayon-line">
                | Server                  ; Section 14.38
</div>
<div id="crayon-5a72977993edd430163106-8" class="crayon-line crayon-striped-line">
                | Vary                    ; Section 14.44
</div>
<div id="crayon-5a72977993edd430163106-9" class="crayon-line">
                | WWW-Authenticate        ; Section 14.47
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 实体头(Entity Header Fields):如果消息带有消息体,实体头用来作为元信息;如果没有消息体,就是为了描述请求的资源的信息。
JavaScript

entity-header = Allow ; Section 14.7 | Content-Encoding ; Section
14.11 | Content-Language ; Section 14.12 | Content-Length ; Section
14.13 | Content-Location ; Section 14.14 | Content-MD5 ; Section
14.15 | Content-Range ; Section 14.16 | Content-Type ; Section 14.17
| Expires ; Section 14.21 | Last-Modified ; Section 14.29 |
extension-header

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977993ee1473891044-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ee1473891044-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977993ee1473891044-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ee1473891044-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977993ee1473891044-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ee1473891044-6">
6
</div>
<div class="crayon-num" data-line="crayon-5a72977993ee1473891044-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ee1473891044-8">
8
</div>
<div class="crayon-num" data-line="crayon-5a72977993ee1473891044-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977993ee1473891044-10">
10
</div>
<div class="crayon-num" data-line="crayon-5a72977993ee1473891044-11">
11
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977993ee1473891044-1" class="crayon-line">
entity-header  = Allow                    ; Section 14.7
</div>
<div id="crayon-5a72977993ee1473891044-2" class="crayon-line crayon-striped-line">
               | Content-Encoding         ; Section 14.11
</div>
<div id="crayon-5a72977993ee1473891044-3" class="crayon-line">
               | Content-Language         ; Section 14.12
</div>
<div id="crayon-5a72977993ee1473891044-4" class="crayon-line crayon-striped-line">
               | Content-Length           ; Section 14.13
</div>
<div id="crayon-5a72977993ee1473891044-5" class="crayon-line">
               | Content-Location         ; Section 14.14
</div>
<div id="crayon-5a72977993ee1473891044-6" class="crayon-line crayon-striped-line">
               | Content-MD5              ; Section 14.15
</div>
<div id="crayon-5a72977993ee1473891044-7" class="crayon-line">
               | Content-Range            ; Section 14.16
</div>
<div id="crayon-5a72977993ee1473891044-8" class="crayon-line crayon-striped-line">
               | Content-Type             ; Section 14.17
</div>
<div id="crayon-5a72977993ee1473891044-9" class="crayon-line">
               | Expires                  ; Section 14.21
</div>
<div id="crayon-5a72977993ee1473891044-10" class="crayon-line crayon-striped-line">
               | Last-Modified            ; Section 14.29
</div>
<div id="crayon-5a72977993ee1473891044-11" class="crayon-line">
               | extension-header
</div>
</div></td>
</tr>
</tbody>
</table>

待续

本来是打算在一篇文章里把HTTP和WebSocket两个协议的大致细节理出来,然后进行对比。可是写着写着就发现篇幅可能会比较长,读起来就不那么友好了,那么刚好就再写第二篇吧。第二篇里会将WebSocket的大致情况描述一下,然后和HTTP适用的场景进行对比。

 

2 赞 15 收藏 1 评论

美洲杯赌球 2

消息体(Message Body)和实体主体(Entity Body)

如果有Transfer-Encoding头,那么消息体解码完了就是实体主体,如果没有Transfer-Encoding头,消息体就是实体主体。

JavaScript

message-body = entity-body | <entity-body encoded as per Transfer-Encoding>

1
2
   message-body = entity-body
                | <entity-body encoded as per Transfer-Encoding>

在request消息中,消息头中含有Content-Length或者Transfer-Encoding,标识会有一个消息体跟在后边。如果请求的方法不应该含有消息体(如OPTION),那么request消息一定不能含有消息体,即使客户端发送过去,服务器也不会读取消息体。

在response消息中,是否存在消息体由请求方法和返回码来共同决定。像1xx,204,304不会带有消息体。

HTTP消息

一个HTTP消息可能是request或者response消息,两种类型的消息都是由开始行(start-line),零个或多个header域,一个表示header域结束的空行(也就是,一个以CRLF为前缀的空行),一个可能为空的消息主体(message-body)。一个合格的HTTP客户端不应该在消息头或者尾添加多余的CRLF,服务端也会忽略这些字符。

header的值不包括任何前导或后续的LWS(线性空白),线性空白可能会出现在域值(filed-value)的第一个非空白字符之前或最后一个非空白字符之后。前导或后续的LWS可能会被移除而不会改变域值的语意。任何出现在filed-content之间的LWS可能会被一个SP(空格)代替。header域的顺序不重要,但建议把常用的header放在前边(协议里这么说的)。

返回码

返回码是一个3位数,第一位定义的返回码的类别,总共有5个类别,它们是:

JavaScript

- 1xx: Informational - Request received, continuing process - 2xx: Success - The action was successfully received, understood, and accepted

  • 3xx: Redirection - Further action must be taken in order to complete the request - 4xx: Client Error - The request contains bad syntax or cannot be fulfilled - 5xx: Server Error - The server failed to fulfill an apparently valid request
1
2
3
4
5
6
7
8
9
10
11
12
13
  - 1xx: Informational - Request received, continuing process
 
  - 2xx: Success - The action was successfully received,
    understood, and accepted
 
  - 3xx: Redirection - Further action must be taken in order to
    complete the request
 
  - 4xx: Client Error - The request contains bad syntax or cannot
    be fulfilled
 
  - 5xx: Server Error - The server failed to fulfill an apparently
    valid request

RFC2616中接着又给出了一系列返回码的扩展,这些都是我们平时会用到的,但是那些只是示例,HTTP1.1不强制通信各方遵守这些扩展的返回码,通信各方在返回码的实现上只需要遵守以上边定义的这5种类别的定义,意思就是,返回码的第一位要严格按照文档中所述的来,其他的随便定义。

任何人接收到一个不认识的返回码xyz,都可以把它当做x00来对待。对于不认识的返回码的响应消息,不可以缓存。

HTTP连接

HTTP1.1的连接默认使用持续连接(persistent connection),持续连接指的是,有时是客户端会需要在短时间内向服务端请求大量的相关的资源,如果不是持续连接,那么每个资源都要建立一个新的连接,HTTP底层使用的是TCP,那么每次都要使用三次握手建立TCP连接,将造成极大的资源浪费。

持续连接可以带来很多的好处:

  1. 使用更少的TCP连接,对通信各方的压力更小。
  2. 可以使用管道(pipeline)来传输信息,这样请求方不需要等待结果就可以发送下一条信息,对于单个的TCP的使用更充分。
  3. 流量更小
  4. 顺序请求的延时更小。
  5. 不需要重新建立TCP连接就可以传送error,关闭连接等信息。

HTTP1.1的服务器使用TCP的流量控制来控制HTTP的流量,HTTP1.1的客户端在收到服务器连接中发过来的error信息,就要马上关闭此链接。关于HTTP连接还有很多细节,之后再详述。

待续

本来是打算在一篇文章里把HTTP和WebSocket两个协议的大致细节理出来,然后进行对比。可是写着写着就发现篇幅可能会比较长,读起来就不那么友好了,那么刚好就再写第二篇吧。第二篇里会将WebSocket的大致情况描述一下,然后和HTTP适用的场景进行对比。

 

2 赞 15 收藏 1 评论

TAG标签:
版权声明:本文由美洲杯赌球发布于计算机教程,转载请注明出处:刨根问底HTTP和WebSocket协议美洲杯赌球