理解HTTP

翻译 2017年01月03日 08:41:56
理解HTTP


HTTP是基于TCP协议的。TCP负责数据传输,而HTTP只是规范了TCP传输的数据的格式,而这个具体的格式,请见后面给出的资料。


HTTP服务的底层实现就是socket编程。


下面基于socket编写一个简单的HTTP server。


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;


class SocketHandler implements Runnable {


    final static String CRLF = "\r\n";   // 1


    private Socket clientSocket;


    public SocketHandler(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }


    public void handleSocket(Socket clientSocket) throws IOException {


        BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream())
                );
        PrintWriter out = new PrintWriter(
                new BufferedWriter( new OutputStreamWriter(clientSocket.getOutputStream())),
                true
                );


        String requestHeader = "";
        String s;
        while ((s = in.readLine()) != null) {
            s += CRLF;  // 2 很重要,默认情况下in.readLine的结果中`\r\n`被去掉了
            requestHeader = requestHeader + s;
            if (s.equals(CRLF)){ // 3 此处HTTP请求头我们都得到了;如果从请求头中判断有请求正文,则还需要继续获取数据
                break;
            }
        }
        System.out.println("客户端请求头:");
        System.out.println(requestHeader);


        String responseBody = "客户端的请求头是:\n"+requestHeader;


        String responseHeader = "HTTP/1.0 200 OK\r\n" +
                "Content-Type: text/plain; charset=UTF-8\r\n" +
                "Content-Length: "+responseBody.getBytes().length+"\r\n" +
                "\r\n";
        // 4 问题来了:1、浏览器如何探测编码 2、浏览器受到content-length后会按照什么方式判断?汉字的个数?字节数?


        System.out.println("响应头:");
        System.out.println(responseHeader);


        out.write(responseHeader);
        out.write(responseBody);
        out.flush();


        out.close();
        in.close();
        clientSocket.close();


    }


    @Override
    public void run() {
        try {
            handleSocket(clientSocket);
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }


}


public class MyHTTPServer {


    public static void main(String[] args) throws Exception {


        int port = 8000;
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("启动服务,绑定端口: " + port);


        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(30);  // 5


        while (true) {  // 6
            Socket clientSocket = serverSocket.accept();
            System.out.println("新的连接"
                    + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
            try {
                fixedThreadPool.execute(new SocketHandler(clientSocket));
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}
这是一个实现HTTP 1.0的服务器,对于所有的HTTP请求,会把HTTP请求头响应回去。 这个程序说明了web服务器处理请求的基本流程,JSP、Servlet、Spring MVC等只是在 这个基础上嫁了许多方法,以让我们更方面的编写web应用。web服务器不仅可以基于多线程, 也可以基于多进程、Reactor模型等。


测试程序:
运行上面的程序。我们使用curl访问http://127.0.0.1(也可以使用浏览器):


$ curl -i http://127.0.0.1:8000
HTTP/1.0 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 106


客户端的请求头是:
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:8000
Accept: */*
Java程序输出:


启动服务,绑定端口: 8000
新的连接/127.0.0.1:36463
新的连接/127.0.0.1:36463客户端请求头:
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:8000
Accept: */*


响应头:
HTTP/1.0 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 106
程序解析:


// 1:定义了HTTP头的换行符。


// 2:in.readLine()的结果默认不带换行符,这里把它加上。(这不是强制的,主要看你的程序逻辑需不需要, 这个程序的目标是把HTTP请求头响应回去)。


// 3:此时s是一个空行,根据HTTP协议,整个请求头都得到了。


// 4:Content-Length的值是字节的数量。


// 5:线程池。


// 6:这个循环不停监听socket连接,使用SocketHandler处理连入的socket,而这个处理是放在线程池中的。


HTTP 1.1:
HTTP 1.1也是在这个思路的基础上实现的,即多个HTTP请求都在一个TCP连接中传输。对于HTTP 1.1,如何区分出每个HTTP请求很重要, 比较简单的可以是用过Content-Length判断一条请求是否结束。如果一个HTTP请求数据较多,往往采用Chunked方式, 可以参考Chunked transfer encoding。

HTTP的简单理解

web使用一种名为HTTP(HyperText Transfer Protocol,超文本传输协议)的协议作为规范,完成从客户端到服务端的一系列流程 当在浏览器的地址栏内输入URL时,根据URL,W...
  • msdnwolaile
  • msdnwolaile
  • 2016年05月04日 17:05
  • 1007

[转]深入理解HTTP协议

来源:http://www.blogjava.net/zjusuyong/articles/304788.html 深入理解HTTP协议 1. 基础概念篇 1.1 介绍   HTTP是Hy...
  • heiyeshuwu
  • heiyeshuwu
  • 2012年05月26日 13:29
  • 17356

谈谈我对HTTP协议的理解

一.HTTP协议版本         这里我只谈我自己经常见到与谈到的,HTTP1.0与HTTP1.1。         HTTP1.0与HTTP2.0的区别主要体现在以下几个方面:         ...
  • zixiaomuwu
  • zixiaomuwu
  • 2017年03月07日 21:04
  • 1395

对HTTP的简单理解

web浏览器、服务器和相关的web应用程序都是通过HTTP相互通信的,HTTP是现代的全球因特网中使用的通用语言。JPEG图片、HTML页面、文本文件、MPEG电影、WAV音频文件、Java程序等都是...
  • uevol14
  • uevol14
  • 2016年03月16日 14:15
  • 380

ios HTTP协议的理解

一、URL (统一资源定位符)1、URL就是资源的地址、位置,互联网上的每个资源都有一个唯一的URL2、URL 基本格式 -> 协议:// 主机地址/路径协议 : 不同的协议,代表不同资源的...
  • qq_18505715
  • qq_18505715
  • 2016年03月30日 17:15
  • 411

深入理解HTTP协议(一)——基础概念篇

1.介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。它的发展是万维网协会(World Wide Web Consortium)和Intern...
  • huangjianxiang1875
  • huangjianxiang1875
  • 2015年03月07日 16:37
  • 1649

iOS基础:HTTP请求理解

Http之Get/Post请求区别  1.HTTP请求格式:        []  在HTTP请求中,第一行必须是一个请求行(request line),用来说明请求类...
  • gongwutianya
  • gongwutianya
  • 2016年07月29日 17:21
  • 376

深入理解HTTP协议(二)——协议详解篇

1.HTTP/1.0和HTTP/1.1的比较 RFC 1945定义了HTTP/1.0版本,RFC 2616定义了HTTP/1.1版本。 1.1建立连接方面 HTTP/1.0 每次请求...
  • huangjianxiang1875
  • huangjianxiang1875
  • 2015年03月07日 16:38
  • 8314

快速理解http协议

爬虫是一个模拟浏览器进行 HTTP 请求的过程。  HTTP协议是什么? 你浏览的每一个网页都是基于 HTTP 协议呈现的,HTTP 协议是互联网应用中,客户端(浏览器)与服务器之间进行数据通...
  • fyrenwu
  • fyrenwu
  • 2017年04月20日 15:33
  • 184

简单的http协议理解

一 HTTP协议 基于HTTP协议的client与server请求包含4个过程: 1.建立TCP套接字连接; 2.发送HTTP请求报文; 3.接收HTTP应答/响应报文; 4.关闭TCP...
  • baixiaoshi
  • baixiaoshi
  • 2015年01月04日 18:54
  • 730
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:理解HTTP
举报原因:
原因补充:

(最多只允许输入30个字)