打算继续刷题的时候发现出现了这个:
不能刷题了,那就来了解一下HTTP协议,虽然本科上过计算机网络,但是记得的东西只能呵呵了,出来混总是要还得。搜索了一下,网络上文字说明很多也很好,这里主要记录一下理解过程和代码。
HTTP协议是TCP/IP协议簇中属于应用层的协议,至于为什么要弄这么多协议和分这么多层协议我觉得就是为了便于功能分离和实现,也便于理解。感觉协议这个东西就是和计算机接口编程里面一样,就是传一个命令规定格式然后传数据,基本原理上大同小异。
HTTP协议是超文本传输协议,是一种请求/响应式的协议。一个客户机与服务器建立连接后,发送一个请求给服务器;服务器接到请求后,给予相应的响应信息。也就是说也就是在客户端和服务器端进行超文本传输的协议。 HTTP是在客户端和服务器端进行超文本传输的请求/响应协议,既然是双方的请求/响应传输协议,那么就得对双方进行协议约定了,宏观上讲HTTP规定了客户端对服务器发送请求的请求格式、服务器响应客户端的响应格式。中间就进行了很多详细和严格的规定了,细节上参考文献已经写的很详细了,下面通过一个例子来解释:
在window的DOS窗口下使用telnet1来观察HTTP协议的运行过程。
telnet
进入telnet模式set localecho
open www.baidu.com 80
80是HTTP默认端口号ctrl+]
进入命令模式,然后回车进行telnet响应模式输入,把下面的请求头粘贴到窗口 按两次回车,发送请求(这里下面两行前面不能有空格,如果复制的时候出问题先复制到记事本删除前面的空格)
GET /index.html HTTP/1.1
HOST: www.baidu.com
上面两行就是非常简单的请求格式了,第一行GET
表示使用GET方式,/index.html
表示请求的页面为根目录下的index.html
斜杠表示根目录不可以省略,或者直接使用www.baidu.com/index.html
,HOST:
表示请求的主机
这时候窗口显示:
GET /index.html HTTP/1.1
HOST: www.baidu.com
HTTP/1.1 200 OK
Date: Sun, 11 May 2014 10:57:37 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: Keep-Alive
Vary: Accept-Encoding
Set-Cookie: BAIDUID=C764FF5A8A8AD30956E3DC9C217951AB:FG=1; expires=Thu, 31-Dec-3
7 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: H_PS_PSSID=5230_1448_5224_6504_4759_6018_6462_6427_6382_6503; path=/
; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Cache-Control: private
Expires: Sun, 11 May 2014 10:57:18 GMT
X-Powered-By: HPHP
Server: BWS/1.1
BDPAGETYPE: 1
BDQID: 0xf407de870017c2d0
BDUSERID: 0
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" conte
nt="text/html;charset=utf-8"><link rel="dns-prefetch" href="//s1.bdstatic.com"/>
...
后面还有一大堆html源码就没有帖上来了。可以看到,上面的GET那一部分就是我们发送给服务器端的请求命令,而下面从HTTP/1.1 200 OK
一直到结尾是服务端发回的响应头和数据,因为请求了index.html这个文档,所以发送了index.html的源文件。
通过上面的列子,基本上已经知道HTTP协议的运作过程了(如果不成功,下载Xshell 输入telnet www.baidu.com 80
然后进行第5步操作)。客户端连接到服务器的80端口(连接这里用到了TCP协议,这里先不涉及),然后发送请求,服务器收到客户端的请求解析请求后发回响应,各种请求方式和格式规定参考连接里面写的非常详细了。
服务器返回状态码做个笔记:
举例:
在Leetcode上看到的那个502就是LeetCode使用的nginx代理返回的,nginx是啥 ?后面慢慢看。
下面是一个python下的简单HTTP请求演示函数(要在python 2下面用,2.7是没问题的,3.x就不行):
# Simple Python function that issues an HTTP request
from socket import *
def http_req(cmd,server, path):
# Creating a socket to connect and read from
s=socket(AF_INET,SOCK_STREAM)
# Finding server address (assuming port 80)
adr=(gethostbyname(server),80)
# Connecting to server
s.connect(adr)
# Sending request
request=cmd+" "+path+" HTTP/1.0\nHOST: "+server+"\n\n"
s.send(request)
# Printing response
resp=s.recv(1024)
while resp!="":
print resp
resp=s.recv(1024)
http_req("GET","haiyangxu.github.io,"/about.html")
参考:
How the web works: HTTP and CGI explained2