HTTP协议理解与应用总结
2016-03-01 14:00
507 查看
总结了自己在实际工作场景中遇到的与http协议相关的一些内容的理解。
Request格式
Response格式
http的状态码有将近60个,我这里主要记录一些常见的非正常情况下产生的状态码,在平常应用中或多或少会碰到,有助于我们去理解和发现问题。
206 - 断点下载时用到,客户端请求了一部分内容,服务器成功把这部分内容返回给它,这时候就是用这个状态。
301 - 永久跳转,原地址不存在了,url被指向到另一个地址。这个主要是搜索引擎相关,影响爬虫的检索行为。
302 - 临时跳转,服务器会返回一个新的url给客户端,客户端可以继续访问这个url来获取内容。
304 - 资源没有改变,客户端可以使用本地缓存的内容,常见于静态内容访问。
413 - 请求实体太大。常见的情况是上传大文件,但超出了服务器(比如nginx)限制。或者请求头或请求体超出了后端的server(比如tomcat)的设置(比如当前域名下cookie太多,超出了请求头限制)
416 - 跟断点续传有关,客户端请求的范围超出了服务器上文件大小。
500 - 服务器内部错误,不能返回正常的结果。比如最常见的应用抛出空指针异常未进行处理。
502 - 网关错误。常见的情况是反向代理后端的服务器(比如resin或tomcat)没有启动。
503 - 服务不可用。比如服务器负载太高或者服务器已经停止服务。
504 - 网关超时。比如请求时长超出了服务器的响应时间限制。
http headers分为请求头(Request Header)和响应头(Response Header)两类。下面是我们经常用到的一些header.
在互联网站的应用中,缓存几乎无处不在,在基于http的服务中,我们也可以对一些不常改变的内容在客户端进行缓存,这样在多次访问中可以复用缓存内容,加快访问速度,提升用户体验。http的协议里规定了一些用于缓存控制的http消息头:
Cache-Control(HTTP/1.1)/Pragma(HTTP/1.0):指示客户端是否进行缓存以及缓存的时间是多长。默认值是private,也就是把内容缓存在用户私有空间。比如:Cache-Control:max-age=86400,must-revalidate,这是告诉客户端所请求的资源缓存一天(max-age单位是秒,相对时间),过期之后必须进行重新检验。
Expires:指定客户端(如果不强制刷新的话)在多长时间里可以不向服务器发请求,直接读本地缓存。
注意:
优先级:Cache-Control > Expires;
详细参数说明:http://condor.depaul.edu/dmumaugh/readings/handouts/SE435/HTTP/node24.html
不同浏览器的不同行为(刷新,后退,地址栏回车等)在实现上可能有差异;
Last-Modified/If-Modified-Since:Last-Modified是服务器端返回给客户端的资源最后修改时间戳,这样,客户端在下次请求时(比如强制刷新)会带上If-Modified-Since参数来校验资源是否有更新,没有更新的话服务器就返回304状态码,客户端直接取本地缓存的资源。这个时候只有请求开销,没有网络传输开销。注意:时间戳必须是格林威治(GMT)时间,比如:Last-Modified:Sat,
19 Oct 2013 09:20:15 GMT
ETag/If-None-Match:ETag是根据文件属性通过一定算法生成的资源标识,也是用来确定客户端请求的资源是否有更新。如果服务器返回了一个ETag值给客户端,那么下次客户端请求时会带上If-None-Match参数来校验资源是否更新,没有更新的就返回304状态码。(效果基本等同于Last-Modified)
注意:
ETag需要计算,对于计算资源紧张的服务器来说是一种消耗,所以有些网站直接不使用ETag;
如果服务器在负载均衡后面,同一个资源的请求可能分发到不同的后端机器上,由于ETag的计算依赖于文件属性,不同机器上内容相同的文件可能生成的ETag不同,这样就可能使本来内容没变的文件通过ETag校验失败。这里有两种解决方案:一是etag计算不依赖于本地机器,比如直接算文件内容的md5值;二是在负载均衡器上把相同的url请求分发到同一台后端机器。
在我们的实际业务场景下,http的缓存具有非常大的用途,下面列举一些:
充分利用客户端的资源,比如一些客户端需要频繁访问的静态文件,像LOGO,广告图等,完全可以缓存在客户端本地。这样可以减少网络请求,加快客户端展示,还能减少服务器请求的压力。
我们的一些静态内容,比如新闻,博客等,在被搜索引擎爬虫抓取的时候,通过控制缓存参数,就可以减少爬虫的抓取频率,减少不必要的资源浪费。
如果我们的静态资源使用了CDN,那么设置了http缓存就可以在CDN节点上保存一份文件,减少CDN的回源次数,减少网络延时和源站服务器压力。
Accept-Ranges:服务端支持断点下载时会返回这个响应头给客户端,当客户端知道这个以后就可以发送断点请求了。
Content-Length:响应信息的长度,告诉客户端当前请求返回了多少数据。这里要注意一下,用head方法提交请求时不会返回具体数据,但是这个Content-Length会返回完整数据的大小。
Range/Content-Range:客户端请求时提交名为Range的header,告诉服务器自己要请求哪部分的数据。比如:Range: bytes=0-1023表示请求第0到1023个字节.然后服务器返回这1024个字节的内容给客户端,响应头中会带上Content-Range。即:Content-Range: bytes 0-1023/4096,这个4096就是文件总大小。客户端下次请求可以从第1024个字节处开始,Range: bytes=1024-xxxx
Accept-Encoding/Content-Encoding:前者是客户端支持接收的消息编码类型。默认是identity,可选值有gzip,compress等。后者是服务器端响应信息的内容编码类型,常用的就是压缩。压缩的好处显而易见,可以大大减少网络传输的开销,相对于服务器端压缩产生的cpu消耗,网络传输的减少显然更实在。常见形式:Content-Encoding:
gzip,deflate,compress.通常我们对html,js,css,xml,json之类的响应结果可以进行压缩传输。
Transfer-Encoding:response header.响应消息的传输编码类型,规定了网络传输的形式。一般都是下面这种形式:Transfer-Encoding: chunked。当服务器产生动态内容,不知道响应信息的具体长度时,可以通过这个指定分块进行传输,处理多少数据就返回多少数据,这样不用等到数据都准备好了一次性返回。结合上面的内容编码,比如gzip,可以分块压缩并进行传输。另外,请注意,在使用这种编码传输时,我们是看不到Content-Length的,因为内容还没有完全生成。
X-Forward-For:request header. 用来标识用户的真实ip,特别是通过代理(正向或反向)访问服务器或是服务器在负载均衡设备后面的情况。格式:X-forward-For:
client,proxy1,proxy2,…最左边的是最接近客户端的ip。
User-Agent:request header.服务器用来识别客户端基本信息的请求头。一般这个在识别搜索爬虫的时候有用,某些场景下也可以用这个来做一些客户端的统计。
Referer:request header.客户端访问服务器时,这个Referer来指定请求来源,比如是从哪个网站链接过来的,我们在一些统计中会经常用到这个。另外,还有一个重要的用途就是在需要资源防盗链的场景中来过滤非法的请求来源(但是,这个referer是客户端可以伪造的)。
Location:response header.在301/302状态码的响应头中,都会带上这个Location头,来指示客户端用新的地址去访问需要的资源。
Connection:request/response header.在http/1.1中,客户端和服务端默认都是保持连接的,也就是Connection:
keep-alive.如果任何一方不想保持连接,都可以把这个值设置为close.默认情况下,客户端和服务端会保持一个长连接,这样客户端就可以用这个连接发送多次http请求,减少频繁创建连接带来的消耗。对于这个参数,在服务端可能要做更多的设置,比如连接keep-alive的时间,服务器内核的一些网络参数设置(针对tcp)。
http请求是无状态的请求,但是在我们的互联网应用中,经常需要标识用户状态信息来完成一些交互性的操作,比如用户认证要记录用户登录状态,购物车应用要记住用户选择的商品,广告投放应用要记录用户的历史浏览行为等等。这里就会用到session和cookie了。
session:是指http请求-响应的过程中客户端与服务器端的交互状态,这些信息被保存在服务器端,比如内存,数据库等。每个session都有一个唯一标识,由服务器生成,这个标识也要在客户端进行保存,这样客户端在下次请求时可以带上这个标识,方便服务器判断客户端的状态。
客户端对session的支持:
通过cookie保存session id,在请求时发送给服务器。
通过url的参数携带session id与服务器通信。
通过表单的隐藏字段携带session id与服务器通信。
session共享的问题:
在分布式应用中,我们的http
server一般都架在反向代理或是负载均衡设备后面,这就会面临一个session共享的问题。也就是同一个用户的多个请求可能被分发到多个不同的机器,如果我们把session保存在机器本地内存中的话,就无法在多个机器间共享用户的session。这个问题,一般来说,我们可以有两种方式来解决:
把session存放到分布式的内存(eg:memcached)或是集中式存储中(eg:database)。
在反向代理或负载均衡设备上把相同用户的请求分发到同一台机器(这里要处理好机器宕机后请求重新分配的问题)。
cookie:在客户端保持状态化信息,每个cookie内容都属于特定的域(domain)和路径(path),出于安全考虑,不同域或路径下的cookie不能共享。
会话cookie:没有指定过期时间,保存在内存,浏览器关闭后就失效。
持久cookie:指定了过期时间,保存在浏览器本地。
详细内容可以参考:http://en.wikipedia.org/wiki/HTTP_cookie
需要注意的是cookie会存在一些安全方面的问题。
在这里我只是总结了自己在工作中遇到的与http协议相关的一些内容的理解,http协议还有很多需要挖掘的东西,也需要不断去探索,对http协议的理解将会给我们的开发应用带来很大的便利。
最后,推荐两个很NB的http调试工具:fiddler(windows)和charles(mac)有http代理功能,对于不是基于浏览器的http应用(比如mobile app),可以用这两个工具来监控http请求。
一、TCP/IP 协议介绍
在介绍 HTTP 协议之前,先简单说一下TCP/IP协议的相关内容。TCP/IP协议是分层的,从底层至应用层分别为:物理层、链路层、网络层、传输层和应用层,如下图所示:
物理层(Physical layer):是参考模型的最低层。该层是网络通信的数据传输介质,由连接不同结点的电缆与设备共同构成。主要功能是:利用传输介质为数据链路层提供物理连接,负责处理数据传输并监控数据出错率,以便数据流的透明传输。
数据链路层(Data link layer):是参考模型的第2层。 主要功能是:在物理层提供的服务基础上,在通信的实体间建立数据链路连接,传输以“帧”为单位的数据包,并采用差错控制与流量控制方法,使有差错的物理线路变成无差错的数据链路。
网络层(Network layer):是参考模型的第3层。主要功能是:为数据在结点之间传输创建逻辑链路,通过路由选择算法为分组通过通信子网选择最适当的路径,以及实现拥塞控制、网络互联等功能。
传输层(Transport layer):是参考模型的第4层。主要功能是向用户提供可靠的端到端(End-to-End)服务,处理数据包错误、数据包次序,以及其他一些关键传输问题。传输层向高层屏蔽了下层数据通信的细节,因此,它是计算机通信体系结构中关键的一层。
会话层(Session layer):是参考模型的第5层。主要功能是:负责维扩两个结点之间的传输链接,以便确保点到点传输不中断,以及管理数据交换等功能。
表示层(Presentation layer):是参考模型的第6层。主要功能是:用于处理在两个通信系统中交换信息的表示方式,主要包括数据格式变换、数据加密与解密、数据压缩与恢复等功能。
应用层(Application layer):是参考模型的最高层。主要功能是:为应用软件提供了很多服务,例如文件服务器、数据库服务、电子邮件与其他网络软件服务。
从应用层至物理层,数据是一层层封装,封装的方式一般都是在原有数据的前面加一个数据控制头,数据封装格式如下:
其中,对于TCP传输协议,客户端在于服务器建立连接前需要经过TCP三层握手,过程如下:
二、HTTP协议
2.1 简介
超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议,自 1990 年起,HTTP 就已经被应用于 WWW 全球信息服务系统。
HTTP 是一种请求/响应式的协议。一个客户机与服务器建立连接后,发送一个请求给服务器;服务器接到请求后,给予相应的响应信息。
HTTP 的第一版本 HTTP/0.9是一种简单的用于网络间原始数据传输的协议;
HTTP/1.0由 RFC 1945 定义 ,在原 HTTP/0.9 的基础上,有了进一步的改进,允许消息以类 MIME 信息格式存 在,包括请求/响应范式中的已传输数据和修饰符等方面的信息;
HTTP/1.1(RFC2616) 的要求更加严格以确保服务的可靠性,增强了在HTTP/1.0 没有充分考虑到分层代理服务器、高速缓冲存储器、持久连接需求或虚拟主机等方面的效能;
安全增强版的 HTTP (即S-HTTP或HTTPS),则是HTTP协议与安全套接口层(SSL)的结合,使HTTP的协议数据在传输过程中更加安全。
2.2 协议结构
HTTP协议格式也比较简单,格式如下:
2.3 HTTP 协议举例
下面是一个HTTP请求及响应的例子:
2.4 请求头格式
a) 通用头(general-header):
Cache-Control:客户端希望服务端如何缓存自己的请求数据,如"Cache-Control: no-cache","Cache-Control: max-age=0";
Connection:客户端是否希望与服务端之间保持长连接,如"Connection: close", "Connection: keep-alive";
Date:只有当请求方法为POST或PUT方法时客户端才可能会有些字段;
Pragma:包含了客户端一些特殊请求信息,如 "Pragma: no-cache" 客户端希望代理或应用服务器不应缓存与该请求相关的结果数据;
Via:一般用在代理网关向应用服务器发送的请求头中,表明该来自客户端的请求经过了网关代理,
格式为:"Via: 请求协议版本 网关标识 [其它信息] ",
如 :" Via: 1.1 webcache_250_199.hexun.com:80 (squid)"
b) 请求头(request-header):
Accept: 表明客户同端可接受的请求回应的媒体类型范围列表。星号“*”用于按范围将类型分组,用“*/*”指示可接受全部类型;用“type/*”指示可接受 type类型的所有子类型,如“ Accept: image/gif, image/jpeg, */*”;
Accept-Charset:客户端所能识别的字符集编码格式,格式:“Accept-Charset: 字符集1[:权重],字符集2[:权重]”,如:“ Accept-Charset: iso-8859-5, unicode-1-1;q=0.8”;
Accept-Language:客户端所能识别的语言,格式:“Accept-Language: 语言1[:权重],语言2[:权重]”,如:” Accept-Language: zh, en;q=0.7”;
Host:客户请求的主机域名或主机IP,格式:“Host: 域名或IP[:端口号]”,如:“Host: www.hexun.com:80“,请求行中若有HTTP/1.1则必须有该请求头;
User-Agent:表明用户所使用的浏览器标识,主要用于统计的目的;
Referer:指明该请求是从哪个关联连接而来;
Accept-Encoding:客户端所能识别的编码压缩格式,如:“Accept-Encoding: gzip, deflate”;
If- Modified-Since:该字段与客户端缓存相关,客户端所访问的URL自该指定日期以来在服务端是否被修改过,如果修改过则服务端返回新的修改后 的信息,如果未修改过则服务器返回304表明此请求所指URL未曾修改过,如:“If-Modified-Since: Fri, 2 Sep 2006 19:37:36 GMT”;
If-None-Match:该字段与客户端缓存相关,客户端发送URL请求的同时发送该字段及标识,如 果服务端的标识与客户端的标识一致,则返回304表明此URL未修改过,如果不一致则服务端返回完整的数据信息,如:“If-None-Match: 0f0a893aad8c61:253, 0f0a893aad8c61:252, 0f0a893aad8c61:251”;
Cookie:为扩展字段,存储于客户端,向同一域名的服务端发送属于该域的cookie,如:“Cookie: MailUserName=whouse”;
c) 实体头(entity-header): (此类头存在时要求有数据体)
Content-Encoding:客户端所能识别的编码压缩格式,如:“Content-Encoding: gzip, deflate”;
Content-Length:客户端以POST方法上传数据时数据体部分的内容长度,如:“ Content-Length: 24”;
Content- Type:客户端发送的数据体的内容类型,如:“Content-Type: application/x-www-form-urlencoded”为以普通的POST方法发送的数据;“Content-Type: multipart/form-data; boundary=---------------------------5169208281820”,则表明数据体由多部分组成,分隔符为 “-----------------------------5169208281820”;
2.5)响应格式
a) 通用头(general-header):
Cache- Control:服务端要求中间代理及客户端如何缓存自己响应的数据,如“Cache-Control: no-cache”,如:“Cache-Control: private” 不希望被缓存,“Cache-Control: public” 可以被缓存;
Connection:服务端是否希望与客户端之间保持长连接,如“Connection: close”, “Connection: keep-alive”;
Date:只有当请求方法为POST或PUT方法时客户端才可能会有些字段;
Pragma:包含了服务端一些特殊响应信息,如 “Pragma: no-cache” 服务端希望代理或客户端不应缓存结果数据;
Transfer-Encoding:服务端向客户端传输数据所采用的传输模式(仅在HTTP1.1中出现),如:“Transfer-Encoding: chunked”,注:该字段的优先级要高于“Content-Length” 字段的优先级;
b)响应头(response-header):
Accept-Ranges:表明服务端接收的数据单位,如:“Accept-Ranges: bytes”, ;
Location:服务端向客户端返回此信息以使客户端进行重定向,如:“Location: http://www.hexun.com”;
Server:服务端返回的用于标识自己的一些信息,如:“ Server: Microsoft-IIS/6.0”;
ETag:服务端返回的响应数据的标识字段,客户端可根据此字段的值向服务器发送某URL是否更新的信息;
c)实体头(entity-header): (此类头存在时要求有数据体)
Content-Encoding:服务端所响应数据的编码格式,如:“Content-Encoding: gzip”;
Content-Length:服务端所返回数据的数据体部分的内容长度,如:“ Content-Length: 24”;
Content-Type:服务端所返回的数据体的内容类型,如:“Content-Type: text/html; charset=gb2312” ;
Set-Cookie:服务端返回给客户端的cookie数据,如:“ Set-Cookie: ASP.NET_SessionId=icnh2ku2dqlmkciyobgvzl55; path=/”
2.6)服务器返回状态码
1xx:表明服务端接收了客户端请求,客户端继续发送请求;
2xx:客户端发送的请求被服务端成功接收并成功进行了处理;
3xx:服务端给客户端返回用于重定向的信息;
4xx:客户端的请求有非法内容;
5xx:服务端未能正常处理客户端的请求而出现意外错误。
举例:
“100” ; 服务端希望客户端继续;
“200” ; 服务端成功接收并处理了客户端的请求;
“301” ; 客户端所请求的URL已经移走,需要客户端重定向到其它的URL;
“304” ; 客户端所请求的URL未发生变化;
“400” ; 客户端请求错误;
“403” ; 客户端请求被服务端所禁止;
“404” ; 客户端所请求的URL在服务端不存在;
“500” ; 服务端在处理客户端请求时出现异常;
“501” ; 服务端未实现客户端请求的方法或内容;
“502” ; 此为中间代理返回给客户端的出错信息,表明服务端返回给代理时出错;
“503” ; 服务端由于负载过高或其它错误而无法正常响应客户端请求;
“504” ; 此为中间代理返回给客户端的出错信息,表明代理连接服务端出现超时。
2.7)chunked 传输
编码使用若干个Chunk组成,由一个标明长度为0的chunk结束,每个Chunk有两部分组成,第一部分是该Chunk的长度(以十六进制表示)和 长度单位(一般不写),第二部分就是指定长度的内容,每个部分用CRLF隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些 没有写的头部内容。另外,在HTTP头里必须含有:” Transfer-Encoding: chunked” 通用头字段。格式如下:
2.8)HTTP 请求方法
GET、POST、HEAD、CONNECT、PUT、DELETE、TRACE、OPTIONS
2.9)HTTP 断点续传
a)HTTP 请求头
格式:Range: bytes={range_from}-{range_to}
该头表示从后端 HTTP 服务器取数据,开始偏移位置为 {range_from},结束偏移位置为 {range_to},其中偏移位置下标从 0 开始;如果省略了 {range_to} 则表示从指定的开始位置 {range_from} 至数据结尾。
如:Range: bytes=1024-2048 其表示读取从偏移位置 1024 至 2028 的数据,而 Range: bytes=1024- 则表示读取从偏移位置 1024 至数据结尾的数据。
b)HTTP 响应头
格式:Content-Range: bytes {range_from}-{range_to}/{total_length}
其中 {range_from} 和 {range_to} 分别代表当前从服务端返回的数据的起始偏移位置(下标从 0 开始),这是一个双向闭区间范围,而 total_length 则指定了整个数据的总长度,此时 HTTP 响应头中的 Content-Length 如果存在,则其值表示当前返回的数据块(由 {range_from} 和 {range_to} 指定的数据区间)的长度。该长度内的数据包括 {range_from} 和 {range_to} 两个位置的数据。
3.0)举例
a)GET请求
Html代码
GET http://photo.test.com/inc/global.js HTTP/1.1
Host: photo.test.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: ASP.NET_SessionId=ey5drq45lsomio55hoydzc45
Cache-Control: max-age=0
b)POST请求
Html代码
POST / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Host: www.test.com
Content-Length: 24
Connection: Keep-Alive
Cache-Control: no-cache
name=value&submitsubmit=submit
c)通过HTTP代理发送GET请求
Html代码
GET http://mail.test.com/ HTTP/1.1
Host: mail.test.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
d)POST方式上传文件
Html代码
POST http://www.test.comt/upload_attach?uidl=%3C HTTP/1.1
Host: www.test.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Content-Type: multipart/form-data; boundary=---------------------------5169208281820
Content-Length: 449
-----------------------------5169208281820
Content-Disposition: form-data; name="file_1"; filename=""
Content-Type: application/octet-stream
-----------------------------5169208281820
Content-Disposition: form-data; name="file_0"; filename="test.txt"
Content-Type: text/plain
hello world!
-----------------------------5169208281820
Content-Disposition: form-data; name="oper"
upload
-----------------------------5169208281820--
e)CONNECT举例
Html代码
CONNECT mail.test.com:80 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Proxy-Connection: keep-alive
Host: mail.test.com:80
3.1)在终端以 telnet 方式测试
a)打开回显功能(针对windows)
Windows 2000:进入DOS模式->输入 telnet->set LOCAL_ECHO->退出:quit->telnet ip 80
Windows xp:进入DOS模式->输入telnet->set local echo->open ip 80
b) 按HTTP协议格式输入GET请求、HEAD请求、POST请求。
Request & Response
Request格式<request-line> 比如:GET /api/index.json HTTP/1.1 <headers> 比如:Accept: */*; User-Agent: Mozilla/4.0;…… <blank line> [<request-body>] 比如:id=1×tamp=xxxxxx
Response格式
<status-line> 比如:HTTP/1.1 200 OK <headers> 比如:Content-Type: application/json;…… <blank line> [<response-body>] 比如:{"id":1,"username":"testuser"}
Status Code
http的状态码有将近60个,我这里主要记录一些常见的非正常情况下产生的状态码,在平常应用中或多或少会碰到,有助于我们去理解和发现问题。206 - 断点下载时用到,客户端请求了一部分内容,服务器成功把这部分内容返回给它,这时候就是用这个状态。
301 - 永久跳转,原地址不存在了,url被指向到另一个地址。这个主要是搜索引擎相关,影响爬虫的检索行为。
302 - 临时跳转,服务器会返回一个新的url给客户端,客户端可以继续访问这个url来获取内容。
304 - 资源没有改变,客户端可以使用本地缓存的内容,常见于静态内容访问。
413 - 请求实体太大。常见的情况是上传大文件,但超出了服务器(比如nginx)限制。或者请求头或请求体超出了后端的server(比如tomcat)的设置(比如当前域名下cookie太多,超出了请求头限制)
416 - 跟断点续传有关,客户端请求的范围超出了服务器上文件大小。
500 - 服务器内部错误,不能返回正常的结果。比如最常见的应用抛出空指针异常未进行处理。
502 - 网关错误。常见的情况是反向代理后端的服务器(比如resin或tomcat)没有启动。
503 - 服务不可用。比如服务器负载太高或者服务器已经停止服务。
504 - 网关超时。比如请求时长超出了服务器的响应时间限制。
Headers
http headers分为请求头(Request Header)和响应头(Response Header)两类。下面是我们经常用到的一些header.
1.缓存控制
在互联网站的应用中,缓存几乎无处不在,在基于http的服务中,我们也可以对一些不常改变的内容在客户端进行缓存,这样在多次访问中可以复用缓存内容,加快访问速度,提升用户体验。http的协议里规定了一些用于缓存控制的http消息头:Cache-Control(HTTP/1.1)/Pragma(HTTP/1.0):指示客户端是否进行缓存以及缓存的时间是多长。默认值是private,也就是把内容缓存在用户私有空间。比如:Cache-Control:max-age=86400,must-revalidate,这是告诉客户端所请求的资源缓存一天(max-age单位是秒,相对时间),过期之后必须进行重新检验。
Expires:指定客户端(如果不强制刷新的话)在多长时间里可以不向服务器发请求,直接读本地缓存。
注意:
优先级:Cache-Control > Expires;
详细参数说明:http://condor.depaul.edu/dmumaugh/readings/handouts/SE435/HTTP/node24.html
不同浏览器的不同行为(刷新,后退,地址栏回车等)在实现上可能有差异;
Last-Modified/If-Modified-Since:Last-Modified是服务器端返回给客户端的资源最后修改时间戳,这样,客户端在下次请求时(比如强制刷新)会带上If-Modified-Since参数来校验资源是否有更新,没有更新的话服务器就返回304状态码,客户端直接取本地缓存的资源。这个时候只有请求开销,没有网络传输开销。注意:时间戳必须是格林威治(GMT)时间,比如:Last-Modified:Sat,
19 Oct 2013 09:20:15 GMT
ETag/If-None-Match:ETag是根据文件属性通过一定算法生成的资源标识,也是用来确定客户端请求的资源是否有更新。如果服务器返回了一个ETag值给客户端,那么下次客户端请求时会带上If-None-Match参数来校验资源是否更新,没有更新的就返回304状态码。(效果基本等同于Last-Modified)
注意:
ETag需要计算,对于计算资源紧张的服务器来说是一种消耗,所以有些网站直接不使用ETag;
如果服务器在负载均衡后面,同一个资源的请求可能分发到不同的后端机器上,由于ETag的计算依赖于文件属性,不同机器上内容相同的文件可能生成的ETag不同,这样就可能使本来内容没变的文件通过ETag校验失败。这里有两种解决方案:一是etag计算不依赖于本地机器,比如直接算文件内容的md5值;二是在负载均衡器上把相同的url请求分发到同一台后端机器。
在我们的实际业务场景下,http的缓存具有非常大的用途,下面列举一些:
充分利用客户端的资源,比如一些客户端需要频繁访问的静态文件,像LOGO,广告图等,完全可以缓存在客户端本地。这样可以减少网络请求,加快客户端展示,还能减少服务器请求的压力。
我们的一些静态内容,比如新闻,博客等,在被搜索引擎爬虫抓取的时候,通过控制缓存参数,就可以减少爬虫的抓取频率,减少不必要的资源浪费。
如果我们的静态资源使用了CDN,那么设置了http缓存就可以在CDN节点上保存一份文件,减少CDN的回源次数,减少网络延时和源站服务器压力。
2.断点请求
Accept-Ranges:服务端支持断点下载时会返回这个响应头给客户端,当客户端知道这个以后就可以发送断点请求了。Content-Length:响应信息的长度,告诉客户端当前请求返回了多少数据。这里要注意一下,用head方法提交请求时不会返回具体数据,但是这个Content-Length会返回完整数据的大小。
Range/Content-Range:客户端请求时提交名为Range的header,告诉服务器自己要请求哪部分的数据。比如:Range: bytes=0-1023表示请求第0到1023个字节.然后服务器返回这1024个字节的内容给客户端,响应头中会带上Content-Range。即:Content-Range: bytes 0-1023/4096,这个4096就是文件总大小。客户端下次请求可以从第1024个字节处开始,Range: bytes=1024-xxxx
3.编码
Accept-Encoding/Content-Encoding:前者是客户端支持接收的消息编码类型。默认是identity,可选值有gzip,compress等。后者是服务器端响应信息的内容编码类型,常用的就是压缩。压缩的好处显而易见,可以大大减少网络传输的开销,相对于服务器端压缩产生的cpu消耗,网络传输的减少显然更实在。常见形式:Content-Encoding:gzip,deflate,compress.通常我们对html,js,css,xml,json之类的响应结果可以进行压缩传输。
Transfer-Encoding:response header.响应消息的传输编码类型,规定了网络传输的形式。一般都是下面这种形式:Transfer-Encoding: chunked。当服务器产生动态内容,不知道响应信息的具体长度时,可以通过这个指定分块进行传输,处理多少数据就返回多少数据,这样不用等到数据都准备好了一次性返回。结合上面的内容编码,比如gzip,可以分块压缩并进行传输。另外,请注意,在使用这种编码传输时,我们是看不到Content-Length的,因为内容还没有完全生成。
4.其他
X-Forward-For:request header. 用来标识用户的真实ip,特别是通过代理(正向或反向)访问服务器或是服务器在负载均衡设备后面的情况。格式:X-forward-For:client,proxy1,proxy2,…最左边的是最接近客户端的ip。
User-Agent:request header.服务器用来识别客户端基本信息的请求头。一般这个在识别搜索爬虫的时候有用,某些场景下也可以用这个来做一些客户端的统计。
Referer:request header.客户端访问服务器时,这个Referer来指定请求来源,比如是从哪个网站链接过来的,我们在一些统计中会经常用到这个。另外,还有一个重要的用途就是在需要资源防盗链的场景中来过滤非法的请求来源(但是,这个referer是客户端可以伪造的)。
Location:response header.在301/302状态码的响应头中,都会带上这个Location头,来指示客户端用新的地址去访问需要的资源。
Connection:request/response header.在http/1.1中,客户端和服务端默认都是保持连接的,也就是Connection:
keep-alive.如果任何一方不想保持连接,都可以把这个值设置为close.默认情况下,客户端和服务端会保持一个长连接,这样客户端就可以用这个连接发送多次http请求,减少频繁创建连接带来的消耗。对于这个参数,在服务端可能要做更多的设置,比如连接keep-alive的时间,服务器内核的一些网络参数设置(针对tcp)。
Session和Cookie
http请求是无状态的请求,但是在我们的互联网应用中,经常需要标识用户状态信息来完成一些交互性的操作,比如用户认证要记录用户登录状态,购物车应用要记住用户选择的商品,广告投放应用要记录用户的历史浏览行为等等。这里就会用到session和cookie了。session:是指http请求-响应的过程中客户端与服务器端的交互状态,这些信息被保存在服务器端,比如内存,数据库等。每个session都有一个唯一标识,由服务器生成,这个标识也要在客户端进行保存,这样客户端在下次请求时可以带上这个标识,方便服务器判断客户端的状态。
客户端对session的支持:
通过cookie保存session id,在请求时发送给服务器。
通过url的参数携带session id与服务器通信。
通过表单的隐藏字段携带session id与服务器通信。
session共享的问题:
在分布式应用中,我们的http
server一般都架在反向代理或是负载均衡设备后面,这就会面临一个session共享的问题。也就是同一个用户的多个请求可能被分发到多个不同的机器,如果我们把session保存在机器本地内存中的话,就无法在多个机器间共享用户的session。这个问题,一般来说,我们可以有两种方式来解决:
把session存放到分布式的内存(eg:memcached)或是集中式存储中(eg:database)。
在反向代理或负载均衡设备上把相同用户的请求分发到同一台机器(这里要处理好机器宕机后请求重新分配的问题)。
cookie:在客户端保持状态化信息,每个cookie内容都属于特定的域(domain)和路径(path),出于安全考虑,不同域或路径下的cookie不能共享。
会话cookie:没有指定过期时间,保存在内存,浏览器关闭后就失效。
持久cookie:指定了过期时间,保存在浏览器本地。
详细内容可以参考:http://en.wikipedia.org/wiki/HTTP_cookie
需要注意的是cookie会存在一些安全方面的问题。
在这里我只是总结了自己在工作中遇到的与http协议相关的一些内容的理解,http协议还有很多需要挖掘的东西,也需要不断去探索,对http协议的理解将会给我们的开发应用带来很大的便利。
最后,推荐两个很NB的http调试工具:fiddler(windows)和charles(mac)有http代理功能,对于不是基于浏览器的http应用(比如mobile app),可以用这两个工具来监控http请求。
一、TCP/IP 协议介绍
在介绍 HTTP 协议之前,先简单说一下TCP/IP协议的相关内容。TCP/IP协议是分层的,从底层至应用层分别为:物理层、链路层、网络层、传输层和应用层,如下图所示:
物理层(Physical layer):是参考模型的最低层。该层是网络通信的数据传输介质,由连接不同结点的电缆与设备共同构成。主要功能是:利用传输介质为数据链路层提供物理连接,负责处理数据传输并监控数据出错率,以便数据流的透明传输。
数据链路层(Data link layer):是参考模型的第2层。 主要功能是:在物理层提供的服务基础上,在通信的实体间建立数据链路连接,传输以“帧”为单位的数据包,并采用差错控制与流量控制方法,使有差错的物理线路变成无差错的数据链路。
网络层(Network layer):是参考模型的第3层。主要功能是:为数据在结点之间传输创建逻辑链路,通过路由选择算法为分组通过通信子网选择最适当的路径,以及实现拥塞控制、网络互联等功能。
传输层(Transport layer):是参考模型的第4层。主要功能是向用户提供可靠的端到端(End-to-End)服务,处理数据包错误、数据包次序,以及其他一些关键传输问题。传输层向高层屏蔽了下层数据通信的细节,因此,它是计算机通信体系结构中关键的一层。
会话层(Session layer):是参考模型的第5层。主要功能是:负责维扩两个结点之间的传输链接,以便确保点到点传输不中断,以及管理数据交换等功能。
表示层(Presentation layer):是参考模型的第6层。主要功能是:用于处理在两个通信系统中交换信息的表示方式,主要包括数据格式变换、数据加密与解密、数据压缩与恢复等功能。
应用层(Application layer):是参考模型的最高层。主要功能是:为应用软件提供了很多服务,例如文件服务器、数据库服务、电子邮件与其他网络软件服务。
从应用层至物理层,数据是一层层封装,封装的方式一般都是在原有数据的前面加一个数据控制头,数据封装格式如下:
其中,对于TCP传输协议,客户端在于服务器建立连接前需要经过TCP三层握手,过程如下:
二、HTTP协议
2.1 简介
超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议,自 1990 年起,HTTP 就已经被应用于 WWW 全球信息服务系统。
HTTP 是一种请求/响应式的协议。一个客户机与服务器建立连接后,发送一个请求给服务器;服务器接到请求后,给予相应的响应信息。
HTTP 的第一版本 HTTP/0.9是一种简单的用于网络间原始数据传输的协议;
HTTP/1.0由 RFC 1945 定义 ,在原 HTTP/0.9 的基础上,有了进一步的改进,允许消息以类 MIME 信息格式存 在,包括请求/响应范式中的已传输数据和修饰符等方面的信息;
HTTP/1.1(RFC2616) 的要求更加严格以确保服务的可靠性,增强了在HTTP/1.0 没有充分考虑到分层代理服务器、高速缓冲存储器、持久连接需求或虚拟主机等方面的效能;
安全增强版的 HTTP (即S-HTTP或HTTPS),则是HTTP协议与安全套接口层(SSL)的结合,使HTTP的协议数据在传输过程中更加安全。
2.2 协议结构
HTTP协议格式也比较简单,格式如下:
2.3 HTTP 协议举例
下面是一个HTTP请求及响应的例子:
2.4 请求头格式
a) 通用头(general-header):
Cache-Control:客户端希望服务端如何缓存自己的请求数据,如"Cache-Control: no-cache","Cache-Control: max-age=0";
Connection:客户端是否希望与服务端之间保持长连接,如"Connection: close", "Connection: keep-alive";
Date:只有当请求方法为POST或PUT方法时客户端才可能会有些字段;
Pragma:包含了客户端一些特殊请求信息,如 "Pragma: no-cache" 客户端希望代理或应用服务器不应缓存与该请求相关的结果数据;
Via:一般用在代理网关向应用服务器发送的请求头中,表明该来自客户端的请求经过了网关代理,
格式为:"Via: 请求协议版本 网关标识 [其它信息] ",
如 :" Via: 1.1 webcache_250_199.hexun.com:80 (squid)"
b) 请求头(request-header):
Accept: 表明客户同端可接受的请求回应的媒体类型范围列表。星号“*”用于按范围将类型分组,用“*/*”指示可接受全部类型;用“type/*”指示可接受 type类型的所有子类型,如“ Accept: image/gif, image/jpeg, */*”;
Accept-Charset:客户端所能识别的字符集编码格式,格式:“Accept-Charset: 字符集1[:权重],字符集2[:权重]”,如:“ Accept-Charset: iso-8859-5, unicode-1-1;q=0.8”;
Accept-Language:客户端所能识别的语言,格式:“Accept-Language: 语言1[:权重],语言2[:权重]”,如:” Accept-Language: zh, en;q=0.7”;
Host:客户请求的主机域名或主机IP,格式:“Host: 域名或IP[:端口号]”,如:“Host: www.hexun.com:80“,请求行中若有HTTP/1.1则必须有该请求头;
User-Agent:表明用户所使用的浏览器标识,主要用于统计的目的;
Referer:指明该请求是从哪个关联连接而来;
Accept-Encoding:客户端所能识别的编码压缩格式,如:“Accept-Encoding: gzip, deflate”;
If- Modified-Since:该字段与客户端缓存相关,客户端所访问的URL自该指定日期以来在服务端是否被修改过,如果修改过则服务端返回新的修改后 的信息,如果未修改过则服务器返回304表明此请求所指URL未曾修改过,如:“If-Modified-Since: Fri, 2 Sep 2006 19:37:36 GMT”;
If-None-Match:该字段与客户端缓存相关,客户端发送URL请求的同时发送该字段及标识,如 果服务端的标识与客户端的标识一致,则返回304表明此URL未修改过,如果不一致则服务端返回完整的数据信息,如:“If-None-Match: 0f0a893aad8c61:253, 0f0a893aad8c61:252, 0f0a893aad8c61:251”;
Cookie:为扩展字段,存储于客户端,向同一域名的服务端发送属于该域的cookie,如:“Cookie: MailUserName=whouse”;
c) 实体头(entity-header): (此类头存在时要求有数据体)
Content-Encoding:客户端所能识别的编码压缩格式,如:“Content-Encoding: gzip, deflate”;
Content-Length:客户端以POST方法上传数据时数据体部分的内容长度,如:“ Content-Length: 24”;
Content- Type:客户端发送的数据体的内容类型,如:“Content-Type: application/x-www-form-urlencoded”为以普通的POST方法发送的数据;“Content-Type: multipart/form-data; boundary=---------------------------5169208281820”,则表明数据体由多部分组成,分隔符为 “-----------------------------5169208281820”;
2.5)响应格式
a) 通用头(general-header):
Cache- Control:服务端要求中间代理及客户端如何缓存自己响应的数据,如“Cache-Control: no-cache”,如:“Cache-Control: private” 不希望被缓存,“Cache-Control: public” 可以被缓存;
Connection:服务端是否希望与客户端之间保持长连接,如“Connection: close”, “Connection: keep-alive”;
Date:只有当请求方法为POST或PUT方法时客户端才可能会有些字段;
Pragma:包含了服务端一些特殊响应信息,如 “Pragma: no-cache” 服务端希望代理或客户端不应缓存结果数据;
Transfer-Encoding:服务端向客户端传输数据所采用的传输模式(仅在HTTP1.1中出现),如:“Transfer-Encoding: chunked”,注:该字段的优先级要高于“Content-Length” 字段的优先级;
b)响应头(response-header):
Accept-Ranges:表明服务端接收的数据单位,如:“Accept-Ranges: bytes”, ;
Location:服务端向客户端返回此信息以使客户端进行重定向,如:“Location: http://www.hexun.com”;
Server:服务端返回的用于标识自己的一些信息,如:“ Server: Microsoft-IIS/6.0”;
ETag:服务端返回的响应数据的标识字段,客户端可根据此字段的值向服务器发送某URL是否更新的信息;
c)实体头(entity-header): (此类头存在时要求有数据体)
Content-Encoding:服务端所响应数据的编码格式,如:“Content-Encoding: gzip”;
Content-Length:服务端所返回数据的数据体部分的内容长度,如:“ Content-Length: 24”;
Content-Type:服务端所返回的数据体的内容类型,如:“Content-Type: text/html; charset=gb2312” ;
Set-Cookie:服务端返回给客户端的cookie数据,如:“ Set-Cookie: ASP.NET_SessionId=icnh2ku2dqlmkciyobgvzl55; path=/”
2.6)服务器返回状态码
1xx:表明服务端接收了客户端请求,客户端继续发送请求;
2xx:客户端发送的请求被服务端成功接收并成功进行了处理;
3xx:服务端给客户端返回用于重定向的信息;
4xx:客户端的请求有非法内容;
5xx:服务端未能正常处理客户端的请求而出现意外错误。
举例:
“100” ; 服务端希望客户端继续;
“200” ; 服务端成功接收并处理了客户端的请求;
“301” ; 客户端所请求的URL已经移走,需要客户端重定向到其它的URL;
“304” ; 客户端所请求的URL未发生变化;
“400” ; 客户端请求错误;
“403” ; 客户端请求被服务端所禁止;
“404” ; 客户端所请求的URL在服务端不存在;
“500” ; 服务端在处理客户端请求时出现异常;
“501” ; 服务端未实现客户端请求的方法或内容;
“502” ; 此为中间代理返回给客户端的出错信息,表明服务端返回给代理时出错;
“503” ; 服务端由于负载过高或其它错误而无法正常响应客户端请求;
“504” ; 此为中间代理返回给客户端的出错信息,表明代理连接服务端出现超时。
2.7)chunked 传输
编码使用若干个Chunk组成,由一个标明长度为0的chunk结束,每个Chunk有两部分组成,第一部分是该Chunk的长度(以十六进制表示)和 长度单位(一般不写),第二部分就是指定长度的内容,每个部分用CRLF隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些 没有写的头部内容。另外,在HTTP头里必须含有:” Transfer-Encoding: chunked” 通用头字段。格式如下:
2.8)HTTP 请求方法
GET、POST、HEAD、CONNECT、PUT、DELETE、TRACE、OPTIONS
2.9)HTTP 断点续传
a)HTTP 请求头
格式:Range: bytes={range_from}-{range_to}
该头表示从后端 HTTP 服务器取数据,开始偏移位置为 {range_from},结束偏移位置为 {range_to},其中偏移位置下标从 0 开始;如果省略了 {range_to} 则表示从指定的开始位置 {range_from} 至数据结尾。
如:Range: bytes=1024-2048 其表示读取从偏移位置 1024 至 2028 的数据,而 Range: bytes=1024- 则表示读取从偏移位置 1024 至数据结尾的数据。
b)HTTP 响应头
格式:Content-Range: bytes {range_from}-{range_to}/{total_length}
其中 {range_from} 和 {range_to} 分别代表当前从服务端返回的数据的起始偏移位置(下标从 0 开始),这是一个双向闭区间范围,而 total_length 则指定了整个数据的总长度,此时 HTTP 响应头中的 Content-Length 如果存在,则其值表示当前返回的数据块(由 {range_from} 和 {range_to} 指定的数据区间)的长度。该长度内的数据包括 {range_from} 和 {range_to} 两个位置的数据。
3.0)举例
a)GET请求
Html代码
GET http://photo.test.com/inc/global.js HTTP/1.1
Host: photo.test.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: ASP.NET_SessionId=ey5drq45lsomio55hoydzc45
Cache-Control: max-age=0
b)POST请求
Html代码
POST / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Host: www.test.com
Content-Length: 24
Connection: Keep-Alive
Cache-Control: no-cache
name=value&submitsubmit=submit
c)通过HTTP代理发送GET请求
Html代码
GET http://mail.test.com/ HTTP/1.1
Host: mail.test.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
d)POST方式上传文件
Html代码
POST http://www.test.comt/upload_attach?uidl=%3C HTTP/1.1
Host: www.test.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Content-Type: multipart/form-data; boundary=---------------------------5169208281820
Content-Length: 449
-----------------------------5169208281820
Content-Disposition: form-data; name="file_1"; filename=""
Content-Type: application/octet-stream
-----------------------------5169208281820
Content-Disposition: form-data; name="file_0"; filename="test.txt"
Content-Type: text/plain
hello world!
-----------------------------5169208281820
Content-Disposition: form-data; name="oper"
upload
-----------------------------5169208281820--
e)CONNECT举例
Html代码
CONNECT mail.test.com:80 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0
Proxy-Connection: keep-alive
Host: mail.test.com:80
3.1)在终端以 telnet 方式测试
a)打开回显功能(针对windows)
Windows 2000:进入DOS模式->输入 telnet->set LOCAL_ECHO->退出:quit->telnet ip 80
Windows xp:进入DOS模式->输入telnet->set local echo->open ip 80
b) 按HTTP协议格式输入GET请求、HEAD请求、POST请求。
相关文章推荐
- 爬虫_83款 网络爬虫开源软件
- 网络数据包传输过程总结
- HTTP协议 - 协议格式
- linux下的CPU、内存、IO、网络的压力测试
- XMLHttpRequest对象的创建与用法
- java给HttpsURLConnection添加信任证书
- http长连接和短连接!
- Xcode7 beta 网络请求报错 App Transport Security policy
- 为HttpsURLConnection添加信任证书
- Determining IP information for eth0… failed; no link present. eth0虚拟网络无法指定IP
- HttpClient实现客户端与服务器的通信
- Java---Socket编程UDP/TCP
- 易观智库:2015年中国网络视频市场及用户研究
- 使用HttpClient实现文件的上传下载
- nginx限制连接数ngx_http_limit_conn_module模块笔记:二
- linux 网络域名ip查询命令
- 网络知识方面的面试题
- MapServer 之 发布网络覆盖数据服务(WCS-Web Coverage Service)
- android之ConnectivityManager简介,网络连接状态
- 基于nghttp2的APNs new API 测试(c实现)