一直比较想写TCP与HTTP之间的关系,HTTP报文是如何通过tcp发送的,HTTP报文形式内容如何。
HTTP请求包含请求行,请求头,请求体
HTTP响应包含响应头,响应头,响应体
下面我准备通过JAVA自带的socket创建一个HTTP服务,这样就可以直到HTTP整个内容了。
public static void main(String[] args) throws Exception { ???????ServerSocket ss = null; ???????Socket socket = null; ???????BufferedReader br = null; ???????BufferedWriter bw = null; ???????try { ???????????//1.创建socket连接 ???????????ss = new ServerSocket(8081); ???????????//循环等待 ???????????while (true) { ???????????????//2.堵塞,直到有新的连接进来 ???????????????socket = ss.accept(); ???????????????//3.设置读写缓冲区 ???????????????br = new BufferedReader(new InputStreamReader(socket.getInputStream())); ???????????????bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); ???????????????String s; ???????????????int contentLength = 0; ???????????????//4.输出请求体中的内容,并且将Content-Length的值赋值给contentLength,确定post请求体的大小 ???????????????while ((s = br.readLine()) != null && !s.isEmpty()) { ???????????????????System.out.println(s); ???????????????????if (s.indexOf("Content-Length") != -1) { ???????????????????????contentLength = Integer.parseInt(s.substring(s.indexOf("Content-Length") + 16)); ???????????????????} ???????????????} ???????????????//5.如果有请求体,通过read方法读取请求体中的内容 ???????????????if (contentLength != 0) { ???????????????????char[] buf = null; ???????????????????if (contentLength != 0) { ???????????????????????buf = new char[contentLength]; ???????????????????????br.read(buf, 0, contentLength); ???????????????????????System.out.println("The data user posted: " + new String(buf)); ???????????????????} ???????????????} ???????????????//6 设置响应体内容 ???????????????bw.write("HTTP/1.1 200 OK\n"); ???????????????bw.write("Content-Type: text/html; charset=UTF-8\n\n"); ???????????????bw.write("<html>\n" + ???????????????????????"<head>\n" + ???????????????????????" ???<title>first page</title>\n" + ???????????????????????"</head>\n" + ???????????????????????"<body>\n" + ???????????????????????" ???<h1>Hello World!" + "</h1>\n" + ???????????????????????"</body>\n" + ???????????????????????"</html>\n"); ???????????????//7.冲刷到浏览器,即使关闭资源,不然可能导致浏览器一直等待服务器数据 ???????????????bw.flush(); ???????????????bw.close(); ???????????????br.close(); ???????????????socket.close(); ???????????} ???????} catch (IOException e) { ???????????e.printStackTrace(); ???????} finally { ???????????//关闭资源 ???????????ss.close(); ???????} ???}
首先我在浏览器中输入http://localhost:8081/?username=tt 网址(使用不同的浏览器请求报文可能有些差异,比如你安装的某些插件
导致插件也会向服务器发出请求),下面来看看这个在服务器接收到的是什么内容
//首先是请求行,包含请求方式,相对路径,HTTP协议,占一行(也就是说后面接上了\n) ???GET /?username=tt HTTP/1.1 ???//之后就是请求体,主要包括Accept,Accept-Language,User-Agent,Accept-Encoding,Host,Connection,每一个都独占一行 ???Accept: text/html, application/xhtml+xml, image/jxr, */* ???Accept-Language: zh-CN ???User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299 ???Accept-Encoding: gzip, deflate ???Host: localhost:8081 ???Connection: Keep-Alive ???//由于GET没有请求体,所以不会出现请求体内容,如果是post请求则会有请求体内容
之后再来看看响应体写法
//1.设置响应体 包含HTTP协议版本,状态码, 状态码说明 ???bw.write("HTTP/1.1 200 OK\n"); ???//2.设置响应头,主要是相应提编码以及MIME类型方便浏览器解析 ???bw.write("Content-Type: text/html; charset=UTF-8\n\n"); ???//3.设置响应体,与HTML类似 ???bw.write("<html>\n" + ???????????"<head>\n" + ???????????" ???<title>first page</title>\n" + ???????????"</head>\n" + ???????????"<body>\n" + ???????????" ???<h1>Hello World!"+"</h1>\n" + ???????????"</body>\n" + ???????????"</html>\n");
HTTP与TCP的关系
原文地址:https://www.cnblogs.com/bufferflies/p/8970566.html