Http协议浅析
来源:互联网 发布:linux scp 下载文件夹 编辑:程序博客网 时间:2024/06/05 10:33
HTTP协议是无状态的
http协议是无状态的,同一个客户端的这次请求和上次请求是没有对应关系,对http服务器来说,它并不知道这两个请求来自同一个客户端。 为了解决这个问题, Web程序引入了Cookie机制来维护状态.
HTTP之请求消息Request
请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
第一部分:请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
第二部分:请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息
第三部分:空行,请求头部后面的空行是必须的
第四部分:请求数据也叫主体,可以添加任意的其他数据。
下面简单写了一个请求页面:http://localhost:8888/login
看看它的请求头
GET /login HTTP/1.1Host: localhost:8888Connection: keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: en-US,en;q=0.8
这个请求没有请求数据
HTTP之响应消息Response
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
第一部分:状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。
第二部分:消息报头,用来说明客户端要使用的一些附加信息
第三部分:空行,消息报头后面的空行是必须的
第四部分:响应正文,服务器返回给客户端的文本信息。
下面看看上面那个请求的响应信息
HTTP/1.1 200 OKContent-Type: text/html;charset='utf-8'Date: Thu, 21 Dec 2017 07:01:45 GMTConnection: keep-aliveTransfer-Encoding: chunked
下面使用telnet命令进行模拟
//1、输入命令telnet localhost 8888//2、输入回车,接着会显示如下内容:Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.//3、输入回车,然后将上面的请求进入输入,如下所示GET /login HTTP/1.1Host: localhost:8888Connection: keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36Accept-Encoding: gzip, deflate, sdchAccept-Language: en-US,en;q=0.8//4、输入回车,显示内容如下:HTTP/1.1 200 OKContent-Type: text/html;charset='utf-8'Date: Thu, 21 Dec 2017 07:28:05 GMTConnection: keep-aliveTransfer-Encoding: chunked141<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>$Title$</title></head><body> <form action="/dologin" method="get"> <input type="text" name="username"><br/> <input type="text" name="password"><br/> <input type="submit" value="登陆"> </form></body></html>0
telnet localhost 8888
也就是说我们的http通信只要遵从其协议就可以进行通信
下面使用代码来实现客户端的请求
import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import java.net.Socket;public class MyBrowser { public static void main(String[] args) { try { Socket browser = new Socket("localhost", 8888); PrintWriter pw = new PrintWriter(browser.getOutputStream(),true); // 封装请求第一行 pw.println("GET /login HTTP/1.1"); // 封装请求头 pw.println("Host: localhost:8888"); pw.println("Connection: keep-alive"); pw.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); pw.println("Upgrade-Insecure-Requests: 1"); pw.println("User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36"); pw.println("Accept-Encoding: gzip, deflate, sdch"); pw.println("Accept-Language: en-US,en;q=0.8"); // 空行 pw.println(); // 封装实体主体 //pw.println("UserName=Mirhunana&Age=18"); // 写入完毕 browser.shutdownOutput(); // 接受服务器返回信息, InputStream in = browser.getInputStream(); // int length = 0; StringBuffer request = new StringBuffer(); byte[] buf = new byte[1024]; // while ((length = in.read(buf)) != -1) { String line = new String(buf, 0, length); request.append(line); } System.out.println(request); //browser.close(); } catch (IOException e) { System.out.println("出现异常了!"); }finally{ } } }
输出结果为:
HTTP/1.1 200 OKContent-Type: text/html;charset='utf-8'Date: Thu, 21 Dec 2017 08:03:55 GMTConnection: keep-aliveTransfer-Encoding: chunked141<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>$Title$</title></head><body> <form action="/dologin" method="get"> <input type="text" name="username"><br/> <input type="text" name="password"><br/> <input type="submit" value="登陆"> </form></body></html>0
上面的服务端是我们自己提前搭建好了的,下面我们自己用代码来实现服务端
import java.io.IOException;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class MyServer { public static void main(String[] args) { try { ServerSocket server = new ServerSocket(8888); System.out.println("服务器启动"); Socket s = server.accept(); byte[] buf = new byte[1024]; PrintWriter pw = new PrintWriter(s.getOutputStream(),true); // 状态行 pw.println("HTTP/1.1 200 OK"); // 封装消息报头 pw.println("Content-Type: text/html;charset='utf-8'"); // 空行 pw.println(); // 封装响应正文 pw.println("<html>"); pw.println("<head>"); pw.println("<title>Mirhunana</title>"); pw.println("</head>"); pw.println("<body>"); pw.println("<p style=\"font-weight: bold;color: red;\">welcome to Server</p>"); pw.println("</body>"); s.close(); server.close(); pw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
上面的服务器的实现是一个单线程的实现,一般情况下的服务器的实现是使用的一个多线程来不断的监听服务端的请求,每次接收到一个请求就创建一个线程来进行处理。
参考文章:
http://www.jianshu.com/p/80e25cb1d81a
http://blog.csdn.net/changhenshui1990/article/details/70052991
- 浅析HTTP协议 (转载)
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- HTTP 协议浅析(上)
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析http协议
- 浅析HTTP协议
- Http协议浅析
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- 浅析HTTP协议
- oracle comment on的用法
- SecureCRT工具下sftp的用法
- Effective C++之三:以对象管理资源
- 常用的三种获取程序运行时间的方法
- 什么是架构
- Http协议浅析
- 【OpenGL ES】帧缓冲区对象FBO
- Matplotlib for presenting results(论文画图matplotlib jupyter文档)
- SpringMVC解决前台向后台传输的乱码问题
- DPDK源码学习——初始化
- 计算机视觉与深度学习(3)
- Oracle数据库控制文件损坏
- Input Text defaultValue 属性
- JS运算符