HTTP协议和SOCKS5协议
版权声明:原创作品,谢绝转载!否则将追究法律责任。
我们平时上网的时候基本上是离不开浏览器的,尤其是搜索资料的时候,那么这个浏览器是如何工作的呢?用的又是什么协议呢?协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则。这就引入了我们今天要的两个主角,即HTTP和SOCK5协议,他们都可以做代理服务器。经过查阅相关资料,终于这这2个协议有点眉目,再次和大家共享一下学习心得。
一.什么是HTTP协议。
1>.HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等;
2>.HTTP在传输层用的是TCP协议。我们知道HTTP是属于应用层的协议;
3>.HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议;
4>.我们在浏览器的地址栏里输入的网站地址叫做URL (Uniform Resource Locator,统一资源定位符)。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成漂亮的网页;
5>.http协议是无状态的,同一个客户端的这次请求和上次请求是没有对应关系,对http服务器来说,它并不知道这两个请求来自同一个客户端。 为了解决这个问题, Web程序引入了Cookie机制来维护状态。
二.打开一个网页需要浏览器发送很多次Request。
1>.. 当你在浏览器输入URL""的时候,浏览器发送一个格式化后的Request去获取 “ ” 的html. 服务器把Response发送回给浏览器.
2>. 浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如图片,CSS文件,JS文件。浏览器会按照自己的规则去获取相应的内容,比如会先显示文字后显示图片等等。
3>. 浏览器会自动再次发送Request去获取文字,图片,CSS文件,或者JS文件。
4>. 等所有的文件都下载成功后。 漂亮的网页就被显示出来了。
三. HTTP的URL介绍。
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI,用来唯一的标识一个资源)来传输数据和建立连接。URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息URL,全称是UniformResourceLocator, 中文叫统一资源定位符(也叫统一资源定位器),它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。具体的格式可归纳为:":"port】【abs_path】。
下面我们举个例子,相信大家就一目了然了,比如:“尹正杰&x=true#第三章”
我们可以用Golang代码来解析一下:
1 /
2 #!/usr/bin/env gorun
3 @author :yinzhengjie
4 Blog:
6 /
7
8 package main
9
10 import (
11 "net/url"
12 "log"
13 "fmt"
14 )
15
16 func main() {
17 s := "尹正杰&x=true#第三章"
18 u,err := url.Parse(s)
19 if err != nil {
20 log.Fatal(err)
21 }
22 fmt.Println("使用的协议是:",u.Scheme)
23 fmt.Println("主机名称是:",u.Host)
24 fmt.Println("端口号是:",u.Port())
25 fmt.Println("当前路径是:",u.Path)
26 fmt.Println("请求信息是:",u.RawQuery)
27 fmt.Println("参数部分是:",u.User)
28 fmt.Println("当前的锚点是:",u.Fragment)
29 }
30
31
32 /
33 1.协议部分:该URL的协议部分为“https:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP,SVN等等本例中使用的是HTTPS协议。在"HTTPS"后面的“//”为分隔符;
34 2.域名部分:该URL的域名部分为“一个URL中,也可以使用IP地址作为域名使用;
35 3.端口部分:跟在域名后面的是端口,我们的端口就是8888,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口,HTTP默认就是80端口;
36 4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/web/yinzhengjie”;
37 5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,
38 那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.html”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名,比如apache的默认文件
39 就是"index.html",当然如果你修改过http的首页配置文件就林当别论啦;
40 6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“第三章”。锚部分也不是一个URL必须的部分;
41 7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“name=尹正杰&x=true”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
42 /
43
44
45
46
47 #以上代码执行结果如下:
48 使用的协议是: https
49 主机名称是:
50 端口号是: 8888
51 当前路径是: /web/yinzhengjie/index.html
52 请求信息是: name=尹正杰&x=true
53 参数部分是:
54 当前的锚点是: 第三章
四.HTTP协议结构。
大家都知道,HTTP(HyperText Transport Protocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616。通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个指示头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。
五.通用头域。
通用头域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。对通用头域的扩展要求通讯双方都支持此扩展,如果存在不支持的通用头域,一般将会作为实体头域处理。
1.请求消息头域:(HTTP Request header)。
使用Fiddler 能很方便的查看Reques header, 点击Inspectors tab ->Request tab-> headers 如下图所示:
header 有很多,比较难以记忆,我们也按照Fiddler那样把header 进行分类,这样比较清晰也容易记忆。
Cache 头域
If-Modified-Since作用: 把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中.例如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT.实例如下图:
If-None-Match作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag. 使用这样的机制将提高网站的性能.例如: If-None-Match: "03f2b33c0bfcc1:0".实例如下图:
Pragma作用: 防止页面被缓存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样Pargma只有一个用法, 例如: Pragma: no-cache.注意: 在HTTP/1.0版本中,只实现了Pragema:no-cache, 没有实现Cache-Control.
Cache-Control作用: 这个是非常重要的规则。 这个用来指定Response-Request遵循的缓存机制。各个指令含义如下:
'''
Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存
处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、
private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。
各个消息中的指令含义如下:
1>.Public指示响应可被任何缓存区缓存。
2>.Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应
消息对于其他用户的请求无效。
3>.no-cache指示请求或响应消息不能缓存
4>.no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
5>.max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
6>.min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
7>.max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
'''
Client 头域
Accept作用: 浏览器端可以接受的媒体类型,例如: Accept: text/html 代表浏览器可以接受服务器回发的类型为 text/html 也就是我们常说的html文档,如果服务器无法返回text/html类型的数据,服务器应该返回一个406错误(non acceptable)。通配符 代表任意类型.例如 Accept: /* 代表浏览器可以处理所有类型,(一般浏览器发给服务器都是发这个)
Accept-Encoding作用: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码);例如: Accept-Encoding: gzip, deflate
Accept-Language作用: 浏览器申明自己接收的语言。 语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等;例如: Accept-Language: en-us
User-Agent作用:告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本.我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)
Accept-Charset作用:浏览器申明自己接收的字符集,这就是本文前面介绍的各种字符集和字符编码,如gb2312,utf-8(通常我们说Charset包括了相应的字符编码方案);例如: Accept-Language: en-us
Cookie/Login 头域
Cookie:作用: 最重要的header, 将cookie的值发送给HTTP 服务器
Entity头域
Content-Length作用:发送给HTTP服务器数据的长度。例如: Content-Length: 38
Content-Type作用:例如:Content-Type: application/x-www-form-urlencoded
Miscellaneous 头域
Referer作用: 提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。例如: Referer:
Transport 头域
Connection例如: Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接例如: Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
Host(发送请求时,该报头域是必需的)作用: 请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的.例如: 我们在浏览器中输入:浏览器发送的请求消息中,就会包含Host请求报头域,如下:此处使用缺省端口号80,若指定了端口号,则变成:Host:指定端口号
2.响应消息头域:(HTTP Response header)。
同样使用Fiddler 查看Response header, 点击Inspectors tab ->Response tab-> headers 如下图所示
我们也按照Fiddler那样把header 进行分类,这样比较清晰也容易记忆。
Cache头域
Date作用: 生成消息的具体时间和日期.例如: Date: Sat, 11 Feb 2012 11:35:14 GMT
Expires作用: 浏览器会在指定过期时间内使用本地缓存例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT
Vary作用:例如: Vary: Accept-Encoding
Cookie/Login 头域
P3P作用: 用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题.例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
Set-Cookie作用: 非常重要的header, 用于把cookie 发送到客户端浏览器, 每一个写入cookie都会生成一个Set-Cookie.例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
Entity头域
ETag作用: 和If-None-Match 配合使用。 (实例请看上节中If-None-Match的实例).例如: ETag: "03f2b33c0bfcc1:0"
Last-Modified:作用: 用于指示资源的最后修改日期和时间。(实例请看上节的If-Modified-Since的实例).例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT
Content-Type作用:WEB服务器告诉浏览器自己响应的对象的类型和字符集,例如:Content-Type: text/html; charset=utf-8; Content-Type:text/html;charset=GB2312; Content-Type: image/jpeg
Content-Length作用:指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程中,Content-Length的方式要预先在服务器中缓存所有数据,然后所有数据再一股脑儿地发给客户端。例如: Content-Length: 19847
Content-Encoding作用:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip
Content-Language作用: WEB服务器告诉浏览器自己响应的对象的语言者。例如: Content-Language:da
Miscellaneous 头域
Server作用:指明HTTP服务器的软件信息。例如:Server: Microsoft-IIS/7.5
X-AspNet-Version作用:如果网站是用ASP.NET开发的,这个header用来表示ASP.NET的版本。例如: X-AspNet-Version: 4.0.30319
X-Powered-By作用:表示网站是用什么技术开发的例如: X-Powered-By: ASP.NET
Transport头域
Connection作用:例如: Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。例如: Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
Location头域
Location作用: 用于重定向一个新的位置, 包含新的URL地址。 实例请看304状态实例。
六.请求消息。
先看Request 消息的结构, Request 消息分为3部分,第一部分叫Request line, 第二部分叫Request header, 第三部分是body. header和body之间有个空行, 结构如下图:
第一行中的Method表示请求方法,比如"POST","GET", Path-to-resoure表示请求的资源, Http/version-number 表示HTTP协议的版本号.当使用的是"GET" 方法的时候, body是为空的,比如我们打开博客园首页的request 如下:
GET HTTP/1.1
Host:
抽象的东西,难以理解,老感觉是虚的, 所谓眼见为实, 实际见到的东西,我们才能理解和记忆。 我们今天用Fiddler,实际的看看Request和Response.下面我们打开Fiddler 捕捉一个博客园登录的Request 然后分析下它的结构, 在Inspectors tab下以Raw的方式可以看到完整的Request的消息, 如下图:
七.响应消息。
我们再看Response消息的结构, 和Request消息的结构基本一样。 同样也分为三部分,第一部分叫Response line, 第二部分叫Response header,第三部分是body. header和body之间也有个空行, 结构如下图:
HTTP/version-number表示HTTP协议的版本号, status-code 和message 请看下节【状态代码】的详细解释.我们用Fiddler 捕捉一个博客园首页的Response然后分析下它的结构, 在Inspectors tab下以Raw的方式可以看到完整的Response的消息, 如下图:
八.状态码。
Response 消息中的第一行叫做状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。状态码用来告诉HTTP客户端,HTTP服务器是否产生了预期的Response.HTTP/1.1中定义了5类状态码, 状态码由三位数字组成,第一个数字定义了响应的类别:
1XX 提示信息 - 表示请求已被成功接收,继续处理;
2XX 成功 - 表示请求已被成功接收,理解,接受;
3XX 重定向 - 要完成请求必须进行更进一步的处理;
4XX 客户端错误 - 请求有语法错误或请求无法实现;
5XX 服务器端错误 - 服务器未能实现合法的请求;
看看一些常见的状态码:
200 OK 最常见的就是成功响应状态码200了, 这表明该请求被成功地完成,所请求的资源发送回客户端如下图, 打开博客园首页:
302 Found 重定向,新的URL会在response 中的Location中返回,浏览器将会自动使用新的URL发出新的Request,例如在IE中输入, HTTP服务器会返回302, IE取到Response中Location header的新URL, 又重新发送了一个Request.
304 Not Modified 代表上次的文档已经被缓存了, 还可以继续使用,例如打开博客园首页, 发现很多Response 的status code 都是304
提示: 如果你不想使用本地缓存可以用Ctrl+F5 强制刷新页面
400 Bad Request 客户端请求与语法错误,不能被服务器所理解;
403 Forbidden 服务器收到请求,但是拒绝提供服务;
404 Not Found;
请求资源不存在(输错了URL)比如在IE中输入一个错误的URL,
500 Internal Server Error 服务器发生了不可预期的错误
503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常
想要了解更多报错信息,请参考:
九.HTTP协议是无状态的和Connection: //代码效果参考:http://hnjlyzjd.com/xl/wz_25350.html
keep-alive的区别。无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。
从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系.HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接).从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接.Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间.
以上内容大部分来自网络,但是以上的内容并不是我本篇博客的重点,想要了解更多请参考可以自行百度,我这里给大家推荐几个网友写的不错的链接:
链接一:
链接二:
链接三:
以上是关于HTTP协议的一个扫盲,接下来我们的部分我们就放弃说关于HTTP协议的介绍,因为它并不是我们的主角,我们的主角是用一种协议来做代理服务器,用于国内的用户FQ,就是突然之间对HTTP很感兴趣,就在网络上查阅一下资料对自己的知识库进行一个扫盲。好了,下面就进入我们的主菜,如果对HTTP和SOCKS5协议都是相当了解和熟悉的小伙伴可以直接越过关于SOCKS5的协议的介绍了,直接去最后看用Golang实现的关于SOCKS5协议FQ的代码吧~由于Golang是基于socks5协议实现的代理,那么我建议还是多少了解一下socks5协议还是相当有好处的,接下来就跟我一起进行socks5协议的探索之旅吧!
十.什么是SOCKS5协议。
SOCKS是一种网络传输协议,主要用于客户端与外网服务器之间通讯的中间传递。SOCKS是"SOCKetS"的缩写【1】。
当防火墙后的客户端要访问外部的服务器时,就跟SOCKS代理服务器连接。这个代理服务器控制客户端访问外网的资格,允许的话,就将客户端的请求发往外部的服务器。这个协议最初由David Koblas开发,而后由NEC的Ying-Da Lee将其扩展到版本4。最新协议是版本5,与前一版本相比,增加支持UDP、验证,以及IPv6。根据OSI模型,SOCKS是会话层的协议,位于表示层与传输层之间。
十一.与HTTP代理的对比。
SOCKS工作在比HTTP代理更低的层次:SOCKS使用握手协议来通知代理软件其客户端试图进行的连接SOCKS,然后尽可能透明地进行操作,而常规代理可能会解释和重写报头(例如,使用另一种底层协议,例如FTP;然而,HTTP代理只是将HTTP请求转发到所需的HTTP服务器)。虽然HTTP代理有不同的使用模式,CONNECT方法允许转发TCP连接;然而,SOCKS代理还可以转发UDP流量和反向代理,而HTTP代理不能。HTTP代理通常更了解HTTP协议,执行更高层次的过滤(虽然通常只用于GET和POST方法,而不用于CONNECT方法)。
SOCKS
Bill希望通过互联网与Jane沟通,但他们的网络之间存在一个防火墙,Bill不能直接与Jane沟通。所以,Bill连接到他的网络上的SOCKS代理,告知它他想要与Jane创建连接;SOCKS代理打开一个能穿过防火墙的连接,并促进Bill和Jane之间的通信。
有关SOCKS协议的技术细节的更多信息,请参阅下面的部分。
HTTP
Bill希望从Jane的Web服务器下载一个网页。Bill不能直接连接到Jane的服务器,因为在他的网络上设置了防火墙。为了与该服务器通信,Bill连接到其网络的HTTP代理。他的网页浏览器与代理通信的方式与他直接连接Jane的服务器的方式相同;也就是说,网页浏览器会发送一个标准的HTTP请求头。HTTP代理连接到Jane的服务器,然后将Jane的服务器返回的任何数据传回Bill。
十二.SOCKS的版本分支。
1.SOCKS 4
下面是客户端向SOCKS 4代理服务器,发送的连接请求包的格式(以字节为单位):
VN
CD
DSTPORT
DSTIP
USERID
NULL
1
1
2
4
variable
1</