Http协议html
1.深刻概念
Http:HyperText Transfer Protocol,便是超文本传输协议。java
2.浅出概念(使用浏览器访问服务器端网页时须要遵循的一系列规则)
Http:将各类不一样浏览器或各类自研客户端的文字信息组织在一块儿的网状文本数据。
协议:多方一块儿约定的一系列规则,而后你们活动必须遵循这些规则,就像法律你们必须遵循才能享受法律提供的保护。
举个栗子:咱们平时去饭店吃饭一般会有如下几个步骤:
1.坐到合适的座位上。
2.服务员拿出菜单点餐。
3.服务员按照点餐菜单下单。
4.服务员上菜。
5.吃饭。
6.买单走人。
这是咱们吃饭一般的步骤,若是我把这些步骤和饭店约定好,每次到了这家饭店就按这个流程来执行,
我要遵循这个步骤来吃饭,一样饭店也要遵循这个步骤提供饭菜,那么我和店家的协议就达成了,从而能够愉快的吃饭。
例如:我天天中午都会去这家饭店吃一份“蛋炒饭”,并按照上边的步骤,且与商家协定好,商家也答应了,就成了所谓的“我和饭店的协议”。
那么到了12点我过去,商家就会主动提供一份“蛋炒饭”而且是加料的特殊待遇,那么这个就是“我和店家提供午饭的协议”的体现。而其余人12点过去
是没有现成蛋炒饭和加料服务的,由于他们没有达成协议。
3.Http原理web
在网络上常常会碰见 WWW 服务应用系统,该应用系统最基本的传输单位是 Web 网页。WWW 服务应用系统的工做方式是基于 B/S 模式,
由 Web 浏览器即B和 Web服务器(服务器)即S来构成,二者之间采用超文本传送协议(HTTP)进行通讯。
HTTP 协议是基于 TCP/IP 协议之上的协议,为浏览器和 Web 服务器之间的应用层协议,是一种通用的、无状态的和面向对象的协议。
当经过 HTTP 协议链接服务器时,通常会经历如下 4 个步骤。数据库
(1)链接:Web 浏览器与 Web 服务器创建链接,打开一个名为 socket(套接字)的虚拟文件,此文件的创建标志着链接创建成功。数组
(2)请求:Web 浏览器经过 Socket 向 Web 服务器提交请求。HTTP 的请求通常是 GET或 POST 命令(POST 用于 FORM 参数的传递)。浏览器
(3)应答:Web 浏览器提交请求后,经过 HTTP 协议传送给 Web 服务器。Web 服务器接到后,进行事务处理,处理结果又经过 HTTP 传回给 Web 浏览器,从而在 Web 浏览器上显示出所请求的页面。缓存
(4)关闭链接:当应答结束后,Web 浏览器与 Web 服务器必须断开,以保证其余 Web浏览器可以与 Web 服务器创建链接。tomcat
例如当 IE 浏览器与 www.test.com:8080/mydir/index.html 创建了链接,
就会发送 GET命令 GET /mydir/index.html HTTP/1.0。主机名为 www.test.com 的 Web 服务器就会从它的文档空间中搜索子目录 mydir 的文件 index.html。
若是找到该文件,Web 服务器把该文件内容传送给相应的 Web 浏览器。
为了可以让浏览器知道传送回文件的类型,Web 服务器首先传送一些 HTTP 头信息,而后传送具体内容(即 HTTP 体信息),HTTP 头信息和 HTTP 体信息之间用一个空行分开。服务器
经常使用的 HTTP 头信息以下。网络
(1)HTTP 1.0 200 OK:这是 Web 服务器应答的第一行,列出服务器正在运行的 HTTP版本号和应答代码。代码“200 OK”表示请求完成。
(2)MIME_Version:1.0:表示 MIME 类型的版本。
(3)content_type:这个头信息很是重要,表示 HTTP 体信息的 MIME 类型。如content_type:text/html 表示传送的数据是 HTML 文档。
(4)content_length:长度值,表示 HTTP 体信息的长度(字节)。
4.客户端和服务端详解
1)客户端
客户端主要职能有两个,一个向服务器发送请求,另外一个是接收服务器返回的报文并解释成友善的信息供咱们阅读。
客户端大概有如下几类:浏览器、咱们本身写的应用程序(桌面应用和APP应用)、其余。咱们在平常生活中使用最多的就是浏览器了。
下面咱们以IE为示例:咱们在地址栏输入网址并巧下回车,浏览器会为咱们作以下的处理:
1解析出协议(http)、域名(www.baidu.com)及访问资源(index.html)
2使用http协议并建立请求报文向服务器端发送请求
3接收到服务器返回的内容并渲染展现。
大部份客户端的工做都由客户端软件进行了包装和处理。但出于学习的目的咱们使用最原始的命令telnet来模拟http请求。telnet服务须要在控制面板打开
点击【开始】--【运行】--输入cmd打开命令行窗口。在命令行窗口中输入telnet www.baidu.com 80而后敲击一下回车
使用快捷键"Ctrl+]"(ctrl+右中括号)来打开本地回显功能,这样咱们能够看到输入到窗口的内容,不然输入的内容不显示。
再次敲击一下回车。
此时出现空白窗口,咱们就能够模拟http请求向服务器发送请求报文了。在窗口中输入:
GET /index.html HTTP/1.1
Host:www.baidu.com
注意此处敲击两下回车。成功后服务器返回的报文会显示在命令行窗口
小结:客户端主要处理发送请求及处理服务器返回的报文。
2)传输内容
(1)URL:URL是寻找信息时所须要的资源位置。经过URL客户端才能找到网络中的大量数据资源 。如:http://www.baidu.com:80/index.html
URL分为三个部分:
第一部分http是URL的方案,方案告诉客户端使用什么样的协议去访问服务器了,也能够是fpt或https等。
第二部分www.baidu.com:80,指服务器的位置。
第三部分 /index.html是资源路径,说明了请求的是服务器上哪一个特定的本地资源。
URL语法:<协议>://<用户名>:<密码>@主机:端口/路径;参数?查询
几乎没有几个URL包含了全部这些组件。
协议:访问服务器时使用的协议类型(FTP,HTTP,HTTPS)
用户名:有些协议须要使用用户名,如FTP匿名用户登陆:ftp://anonymous@cncoder.me
密码:有些协议须要使用密码,如FTP用户名密码登陆:ftp://username:password@cncoder.me
主机:资源服务器的域名或IP地址
端口:服务器监听的端口号,http协议默认是80端口。
路径:服务器上本地资源的路径。用“/”来分格。如:/theme/image/logo.png
参数:某些协议会输入指定的参数,参数以name:value形式出现,中间用“;”来分格。
查询:用“?”与其余的组件分格开,并用“&”来分隔查询。如:?id=1&name=cncoder
(2)报文:HTTP报文能够分为两类:请求报文和响应报文,请求报文会向服务器请求一个动做,响应报文会将请求的结果返回给客户端。请求报文和响应报文的结构基本相同。
下面为咱们获取服务器上一张图片的报文。
请求报文:
GET /Theme/Image/logo.png HTTP/1.1
Host:www.cncoder.me
响应报文:
HTTP/1.1 200 OK
Content-Type:image/gif
Conetnt-Length4567
请求报文的格式:
<方法><资源路径><协议版本>
<报文头信息>
<报文体信息>
响应报文格式:
<协议版本><状态码><缘由短语>
<报文头信息>
<报文体信息>
请求报文和响应报文只有起始行的语法不一样。
常见请求报文头信息
Host:” www.cncoder.me”
User-Agent:"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"
Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Accept-Language:"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"
Accept-Encoding:"gzip, deflate"
Connection:"keep-alive"
常见响应头信息
Content-Encoding:"gzip"
Content-Length:"1779"
Content-Type:"text/html"
Date:"Sun, 21 Aug 2016 11:45:07 GMT"
Last-Modified:"Sun, 21 Aug 2016 11:33:32 GMT"
Server:"Microsoft-IIS/7.5"
X-Powered-By:"ASP.NET"
(2.1)方法:请求的起始行以方法做为起始,方法用来告诉服务器要如何作。如:GET /index.html HTTP/1.1 中的GET就是方法
1.GET 请求指定的页面信息,并返回实体主体。
2.HEAD 相似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3.POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会致使新的资源的创建和/或已有资源的修改。
4.PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5.DELETE 请求服务器删除指定的页面。
6.CONNECT HTTP/1.1协议中预留给可以将链接改成管道方式的代理服务器。
7.OPTIONS 容许客户端查看服务器的性能。
8.TRACE 回显服务器收到的请求,主要用于测试或诊断。
在开发过程当中咱们最经常使用的就是GET和POST方法。
(2.2)状态码:当客户端发起一次http请请求后,服务器会返回一个包含HTTP状态码的信息头(server header)用以响应客户端的请求。HTTP状态码的英文为HTTP Status Code。
1.100~199 信息,服务器收到请求,须要请求者继续执行操做
2.200~299 成功,操做被成功接收并处理
3.300~399 重定向,须要进一步的操做以完成请求
4.400~499 客户端错误,请求包含语法错误或没法完成请求
5.500~599 服务器错误,服务器在处理请求的过程当中发生了错误
经常使用状态码以下:
200-请求成功
403(禁止)服务器拒绝请求。
404-请求的资源不存在
500-内部服务器错误
502(错误网关)服务器做为网关或代理,从上游服务器收到无效响应。
503(服务不可用)服务器目前没法使用(因为超载或停机维护)。一般,这只是暂时状态。
3)服务器
(0) 服务器软件一直在监听端口是否有新的请求到达,如iis或tomcat在创建web站点后,默认会一直监听80端口等待http请求到过服务器。
(1) 创建链接:若是客户端已经打开一条到服务器的持久链接,则能够直接使用,不然,客户端须要在服务器打开一条新的链接。
(2) 接收请求报文:链接上有数据到过期,Web服务器会从网络链接中读取数据,并将请求报文中的内容解析出来。
如请求报文
GET /index.html HTTP/1.1CRLF
Host:www.cncoder.me
Accept:text/htmlCRLF
接收后会被表示为
Name:Method Value:GET
Name:Uri Value:index.html
Name:Version 1.1
Name:Host Value:www.cncoder.me
Name:Accept Value:test/html
(3) 处理请求:当请求被接收和表示后,服务器即可以根据请求报文进行处理了。如:POST方法中提出报文主体的数据并插入到数据库中。
(4) 访问资源:请求处理完成后,好比Web会根据数据生成一系列的HTML页面或图片等信息。此步骤将访问这些存储在服务器上的物理文件。
(5) 构建响应:Web服务器在识别资源后,构造响应报文。响应报文中包含状态码、首行、主体等内容。
(6) 发送响应:服务器将响应的数据发送给客户端机器。
(7) 记录日志:请求结束会Web服务器会在日志文件中添加一条请求记录。
(8)手写WEB服务器
(8.1)实现HTTP协议原理WEB服务器
当建立实现 HTTP 协议的 Web 服务器时,通常都会根据 HTTP 协议的工做原理,经历固定的步骤。具体步骤以下。
(1)建立 ServerSocket 类对象,监听端口 8080。这是为了区别于 HTTP 的标准 TCP/IP端口 80 而取的。
(2)等待、接受客户机链接到端口 8080,获得与客户机链接的 socket。
(3)建立与 socket 套接字相关联的输入流 instream 和输出流 outstream。
(4)从与 socket 关联的输入流 instream 中读取一行客户机提交的请求信息,请求信息的格式为 GET 路径/文件名 HTTP/1.0。
(5)从请求信息中获取请求类型。若是请求类型是 GET,则从请求信息中获取所访问的 HTML 文件名。没有 HTML 文件名时,则以 index.html 做为文件名。
(6)若是 HTML 文件存在,则打开 HTML 文件,把 HTTP 头信息和 HTML 文件内容经过 Socket 传回给 Web 浏览器,而后关闭文件;不然发送错误信息给 Web 浏览器
(7)关闭与相应 Web 浏览器链接的 socket 套接字。
8.2构建步骤
首先建立了一个实现与浏览器通讯的工具类,而后再建立了调用工具类的 Web 服务器类,最后为了测试 Web 服务器的功能,建立了一个简单的网页。
8.3使用JAVA实现
建立CommunicateThread.java 类用来实现与浏览器的通讯功能
public class CommunicateThread extends Thread { Socket client; // 建立链接 Web 浏览器的 Socket 类对象 int counter; // 建立计数器对象 public CommunicateThread(Socket cl, int c) { client = cl; counter = c; } //实现 run()方法 public void run() { try { //获取客户端的 IP 地址变量 String destIP = client.getInetAddress().toString(); //获取客户机端口号 int destport = client.getPort(); //建立 PrintStream 输出流对象 PrintStream outstream = new PrintStream(client.getOutputStream()); //建立输入流的过滤对象 DataInputStream instream = new DataInputStream(client.getInputStream()); //读取 Web 浏览器提交的请求信息 String inline = instream.readLine(); System.out.println("Received:" + inline); //判断请求信息 //当为 GET 请求时 if (getrequest(inline)) { String filename = getfilename(inline); //获取文件的名字 File file = new File(filename); //建立网页的 file 对象 if (file.exists()) { //当文件存在,则回送给浏览器 //设置返回信息 System.out.println(filename + " requested."); outstream.println("HTTP/1.0 200 OK"); outstream.println("MIME_version:1.0"); outstream.println("Content_Type:text/html"); int len = (int) file.length(); outstream.println("Content_Length:" + len); outstream.println(""); sendfile(outstream, file); //调用 sendfile()方法发送文件 outstream.flush(); } else { //当文件不存在时 //建立显示的内容 String notfound = "<html><head><title>Not Found</title></head><body><h1>Error 404-file not found</h1></body></html>"; //设置返回的信息 outstream.println("HTTP/1.0 404 no found"); outstream.println("Content_Type:text/html"); outstream.println("Content_Length:"+notfound.length()+2); outstream.println(""); outstream.println(notfound); outstream.flush(); } } long time = 1; while (time < 11100000) { time++; } //延时 client.close(); } catch (IOException e) { System.out.println("Exception:" + e); } } boolean getrequest(String s) { // 判断请求的类型是否为 GET if (s.length() > 0) { if (s.substring(0, 3).equalsIgnoreCase("GET")) return true; } return false; } String getfilename(String s) { // 实现文件名的获取 String f = s.substring(s.indexOf(' ') + 1); f = f.substring(0, f.indexOf(' ')); try { if (f.charAt(0) == '/') f = f.substring(1); } catch (StringIndexOutOfBoundsException e) { System.out.println("Exception:" + e); } if (f.equals("")) f = "index.html"; return f; } void sendfile(PrintStream outs, File file) { // 实现发送文件到浏览器的功能 try { // 对象 file 的输入流对象 DataInputStreamin = newDataInputStream(newFileInputStream(file)); int len = (int) file.length(); // 获取文件的长度 byte buf[] = new byte[len]; // 建立字节数组 in.readFully(buf); // 读取内容存储到数组 buf 中 outs.write(buf, 0, len); // 输出数组 buf 中的内容 // 输入流和输出流 outs.flush(); in.close(); } catch (Exception e) { System.out.println("Error retrieving file."); System.exit(1); } } }
代码解析
为了便于实现相应功能,代码中建立了 3 个方法
getrequest()方法用来检测客户的请求是否为 GET
getfilename(s)方法是从客户请求信息 s 中获取要访问的 HTML文件名
sendfile()方法把指定文件内容经过 Socket 传回给 Web 浏览器
线程子类主要用来实现两个功能,即分析 Web 浏览器提交的请求及把应答信息传回给 Web 浏览器
建立实现 Web 服务器的类WebServer.java 类用来实现 Web 服务器,该类主要经过调用 CommunicateThread 类
public class WebServer { public static void main(String args[]) { // 建立两个端口号和链接次数的变量 int i = 1, PORT = 8080; ServerSocket server = null; // 建立 ServerSocket 对象 Socket client = null; // 建立 Socket 对象 try { server = new ServerSocket(PORT); // 为对象 ServerSocket 赋值 // 输出相应的信息 System.out.println("Web Server is listening on port "+ server.getLocalPort()); for (;;) { // 经过无限循环来不断的接收监听 // 获取客户机的链接请求 client = server.accept(); // 建立 CommunicateThread 对象并启动 new CommunicateThread(client, i).start(); i++; // 实现变量 i 的自增 } } catch (Exception e) { System.out.println(e); } } }
在上述代码中首先建立 ServerSocket 对象,而后经过该对象的 accept()方法不停地接收请求,若是链接成功,则调用 CommunicateThread 类的 start()方法来处理请求。
建立浏览器请求页面
当浏览器发送请求到 Web 服务器时,实际状况是 Web 服务器会根据浏览器的请求返
回相应的内容,本项目只是简单地返回固定的名为 index.html 的网页
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-8">
<TITLE>Java Web 服务器</TITLE>
</HEAD>
<BODY>
<!--设置主题-->
<h3>
WEB 服务器主页
</h3>
<hr> <!--设置横线-->
</BODY>
</HTML>
6.扩展内容引导 1. Web的组件结构中还包含代理、缓存、网关、隧道。 2. HTTP协议是创建在TCP/IP协议基础之上。 3. HTTP性能很大一方面在于创建链接。HTTP/1.0时使用Keep-Alive。HTTP/1.1使用管道链接。