Last updated
Last updated
#curl -v -d '{"str_info":"meetbill"}' "http://127.0.0.1:8585/x/hello"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8585 (#0)
> POST /x/hello HTTP/1.1
> Host: 127.0.0.1:8585
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 23
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 23 out of 23 bytes
< HTTP/1.1 200 OK
< meetbill: 1.0.1
< Content-Length: 38
< butterfly: 1.0.5
< x-reqid: EDD1FFCB01842079
< x-cost: 0.008146
< Date: Sun, 20 Oct 2019 12:21:05 GMT
< Server: XXXXXXXXX
<
* Connection #0 to host 127.0.0.1 left intact
{"stat": "OK", "str_info": "meetbill"}
POST /x/hello HTTP/1.1\r\n
Host: 127.0.0.1:8585\r\n
User-Agent: curl/7.54.0\r\n
Accept: */*\r\n
Content-Length: 23\r\n
Content-Type: application/x-www-form-urlencoded\r\n
\r\n
{"str_info":"meetbill"}
CRLF 是 Carriage-Return Line-Feed 的缩写,意思是回车换行,就是回车 (CR, ASCII 13, \r) 换行 (LF, ASCII 10, \n)
HTTP 是基于 TCP 的上层应用协议,tcp 是数据流,这里有两个要点:
(1) 数据没有边界
你可以理解为水在一个水管里的流动,我们不知道哪段数据是一个我们需要的完整数据
(2) 收发有缓冲区
比如:当水从一端流到了另一端,我们在收数据的时候,不可能每来一滴水就处理一次,这个缓冲区就相当于有了一个水桶,再接了一定的水之后内核再给数据交到用户空间,这样可以大大提升性能。
那这里就有一个问题:由于这个特性,内核无法知道哪部分数据是你想要的,所以应用层拿到数据可能是完整数据,也可能是不完整或者一部分完整、一部分不完整(粘包),那么怎样能得到想要的数据呢?
http/1.1 之前,每次请求响应都使用新的 tcp 连接,所以不需要考虑数据边界问题。
http/1.1 支持 keep-alive,多个 message 可以使用同一个 tcp 连接,所以要有确定边界的机制。或者无视客户端的 Connection: keep-alive 头,一律返回 Connection: close,就不用操心这个问题了。