HTTP协议详解

</pre>HTTP协议<p></p><p><span style="font-size:18px">一.HTTP协议基础</span></p><p><span style="font-size:14px">1.定义</span>:HTTP是基于TCP连接的浏览器与服务器通信协议。(即传输层先用TCP三次握手建立连接,进而HTTP通信)</p><p><span style="font-size:14px">2.连接原理</span>:先进行TCP建立端到端连接,然后发送和接受HTTP报文。TCP(Socket)是端到端的连接,通过IP地址和端口号用于定位网络上两台主机的具体运行程序。所以HTTP连接会先启动TCP连接来建立与服务器软件的连接,然后发送和接受HTTP报文内容。</p><p>所以当运行抓包器,打开网页时,会看到一个TCP连接和HTTP连接。在用HTTP 1.0版本时,每打开一个网页就会TCP连接一次。而TCP的每次连接都消耗系统资源(包括CPU和内存)。HTTP1.1版本的TCP连接时持续连接,及请求头默认设置KEEP-ALive=TRUE。这种情况用一份TCP连接传输多次请求。</p><p><span style="font-size:14px">3.模拟发送/响应HTTP报文</span></p><p>故:完全可以用Java Socket编写程序模仿客户端浏览器发送http请求。当然,即可实现客户端软件的文件下载功能。</p><p>代码如下:</p><p></p><pre code_snippet_id="1802010" snippet_file_name="blog_20160802_2_2401736" name="code" class="java">try {       <span style="color:#ff0000;"><strong>//模拟发送http请求</strong></span>
            Socket s = new Socket(InetAddress.getLocalHost(), 8080);  
            OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream());  
            StringBuffer sb = new StringBuffer();  
            sb.append("GET /HttpStream/gb2312.jsp HTTP/1.1\r\n");  
            sb.append("Host: localhost:8088\r\n");  
            sb.append("Connection: Keep-Alive\r\n");  
            //注,这是关键的关键,忘了这里让我搞了半个小时。这里一定要一个回车换行,表示消息头完,不然服务器会等待  
            sb.append("\r\n");  
            osw.write(sb.toString());  
            osw.flush();  
  
            <strong><span style="color:#ff0000;">//模拟读取HTTP响应 </span></strong>
            InputStream is = s.getInputStream();  
            String line = null;  
            int contentLength = 0;//服务器发送回来的消息长度  
            // 读取所有服务器发送过来的请求参数头部信息  
            do {  
                line = readLine(is, 0);  
                //如果有Content-Length消息头时取出  
                if (line.startsWith("Content-Length")) {  
                    contentLength = Integer.parseInt(line.split(":")[1].trim());  
                }  
                //打印请求部信息  
                System.out.print(line);  
                //如果遇到了一个单独的回车换行,则表示请求头结束  
            } while (!line.equals("\r\n"));  
  
            //--输消息的体  
            System.out.print(readLine(is, contentLength));  
  
            //关闭流  
            is.close();  
  
        } catch (UnknownHostException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
          //readLine()方法实现未给出,因为我感觉那个读取方法的效率不高。有兴趣可参考原作者代码。
(代码转自http://blog.csdn.net/a9529lty/article/details/7174265,感谢原作者)

2.关于http文件上传和下载

Socket模拟HTTP上传文件代码

<span style="font-size:12px;">try {
File file=new File("c:/雪狼突击队.jpg");
//将文件读成字符串
String picString=readFileAsString(file.toString());
//URLEncode
picString="picdata="+URLEncoder.encode(picString, "UTF-8");
String url="http://localhost:8080/Test/index.jsp?uid=1&username=test&auth=098f6bcd4621d373cade4e832627b4f6";
Socket socket =new Socket(InetAddress.getByName(url),80);
DataOutputStream dos=new DataOutputStream(socket.getOutputStream()); 
String message=""
+"POST "+url+" HTTP/1.1 \r\n "
+"Host: test.lingye.com \r\n "+"Accept: */* \r\n "
+"Cache-Control:no-cache \r\n" +"User-Agent: MSIE6.0; \r\n "
+"Content-Type: application/x-www-form-urlencoded \r\n " 
+"Content-Length: "+picString.length()+" \r\n "
+"Connection: Close \r\n\r\n"//报头以两个\n作为结束标志
+picString+"\r\n ";//post数据 
byte buffer[]=message.getBytes(); 
dos.write(buffer);
dos.flush();
dos.close();
//以上只进行了发送操作
socket.close();
} catch (Exception e) {
e.printStackTrace();
} 
}</span>
<span style="font-size:12px;"></span><pre style="white-space: normal; font-size: 14px; line-height: 21px;"><pre name="code" class="java"><span style="color:#464646;background-color: rgb(234, 247, 253);">//服务器端
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String </span><span style="color:#ff0000;background-color: rgb(234, 247, 253);"><strong><u>picdata</u></strong></span><span style="color: rgb(70, 70, 70); background-color: rgb(234, 247, 253);">=request.getParameter("</span><span style="color: rgb(70, 70, 70); background-color: rgb(255, 0, 0);"><strong>picdata</strong></span><span style="background-color: rgb(234, 247, 253);"><span style="color:#464646;">");//</span><span style="color:#ff0000;"><strong>注意这里的picData是图片对应的Encode编码方式,同一个编码和同一个解码方式</strong></span><span style="color:#464646;">
BASE64Decoder base64=new BASE64Decoder();
//64位解码
byte[] buffer=base64.decodeBuffer(picdata);
//写进文件
FileOutputStream fos=new FileOutputStream("c:/雪狼突击队1.jpg");
fos.write(buffer);
fos.flush();
fos.close();
fos=null;
}</span></span>


 
 (代码转自http://blog.sina.com.cn/s/blog_5da93c8f0100vj3v.html,感谢作者)  

以上可以看出,Java语言可以编写浏览器,当然浏览器功能很复杂。浏览器对http响应的html代码进行解析,就形成了我们看到的网页。

注意看socket模拟http请求和响应的方法,可以看出读取输入流/输出流都是在一个socket连接中获得的,即每次TCP连接(3次握手后),都会有一个对应的输入和输出。利用该输入输出流就可以发送和接受数据。

4.协议内容详解

参考http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html,协议具体内容讲解很详细


5.关于http1.0和http1.1的持续连接与非持续连接

HTTP/1.0和HTTP/1.1都有非持续连接(non-persistent connection)和持续连接(persistent connection)功能。非持续连接是指启动一次TCP连接服务机就向客户机传送一个对象,而持续连接是指服务机可在相同的TCP连接上向客户机发送多个对象。HTTP/1.0的默认设置是非持续连接,而HTTP/1.1的默认设置是持续连接。

在使用HTTP/1.0的情况下,如果打开一个包含一个HTML文件和10个内联图象对象的网页时,HTTP就要建立11次TCP连接才能把文件从服务机传送到客户机。而使用HTTP/1.1的情况下,如果打开同样的文件时,HTTP建立一次TCP连接就可把文件从服务机传送到客户机。使用一次TCP连接传送一个对象的效率比较低,这体现在下列几个方面:

(1) 每次TCP连接必需要建立和断开。客户机和服务机建立一次连接需要执行三向沟通连接法(three-way handshake),服务机在对象递送之后要断开TCP连接。在建立和断开连接时要占用CPU的资源。如果使用一次连接代替11次连接的话,占用客户机和服务机的CPU时间可大大减少。

(2) 对每次连接,客户机和服务机都必须分配发送和接收缓存。这就意味着要影响客户机和服务机的存储器资源,这同样要占用CPU的时间。

(3) 对由大数量对象组成的文件,TCP的低速启动算法(slow start-up algorithm)会限制服务机向客户机传送对象的速度。使用HTTP/1.1之后,大多数对象都可以尽最大的速率传送。

由于HTTP/1.1允许持续连接,文件中的所有对象都可在相同的TCP连接上传送。HTTP/1.1也允许在客户机接收到服务机的消息响应之前发送多个消息请求,这叫做流水线式请求(pipelined request)。

(此段转自http://blog.chinaunix.net/uid-9681606-id-1998549.html,感谢作者贡献)


6.

请问为什么get方式的请求消息中没有实体内容呢?

使用Get方式的请求消息中不能包含实体内容,只有post方式的请求消息中才可以包含实体内容
,我有点疑问,为什么get方式的请求消息中没有实体内容,请求消息中的实体内容值的什么啊,参数不是实体内容吗?

回答:
这位朋友可能还不太了解http协议
一个完整的请求消息包含:一个请求行 若干消息头,以及实体内容;
其中的一些消息头和实体内容都是可选的!!!!
而在get与post方式中
如一个form表单吧
由于get方式是不包含实体内容的,实体内容就(也就是表单的数据)以参数的形式在url地址后面出现
post是包含实体内容的,它把表单数据放入实体内容里面,以'实体内容'的形式传输
get方式的数据量是有限制的 一般在1kb以下,而post方式则要大的多了!
由此你也可有看出 参数和实体内容的区别了吧;;;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HTTP 协议(Hypertext Transfer Protocol)是一种用于传输超文本的应用层协议,是万维网数据传输的基础。它采用客户端-服务器模式,客户端发起请求,服务器返回响应。下面对 HTTP 协议进行详细解析。 HTTP 协议以简洁的请求-响应模型为基础。客户端发送请求报文给服务器,报文包含请求方法、URL、协议版本等信息。服务器收到请求后,根据请求内容进行相应处理,并返回响应报文给客户端。响应报文包含协议版本、状态码、响应头和响应体等信息。客户端接收到响应后,根据状态码判断请求是否成功,并解析响应内容。 HTTP 协议的特点主要包括:无状态、可靠性差、传输效率低。无状态指的是服务器不会保存任何客户端的状态信息,每次请求都是单独的。可靠性差是因为 HTTP 使用 TCP 进行数据传输,TCP 协议本身也有一定的不可靠性。传输效率低是由于 HTTP 建立连接的开销较大,并且每次请求都需要重新建立连接。 HTTP 协议的工作流程如下:客户端发送一条请求到服务器,服务器接收并解析请求,处理请求并生成响应,将响应发送给客户端,客户端接收并解析响应。 HTTP 协议的主要优点包括:易于使用、灵活性强、便于扩展。易于使用指的是 HTTP 的语法规则简单明了,易于理解和实现。灵活性强指的是可以通过设置请求头、传递参数等方式来定制请求。便于扩展指的是可以根据需要添加新的功能或特性。 总之,HTTP 协议作为互联网应用最常用的协议之一,它的设计简洁、易于使用,为用户提供了方便、快速的网络通信方式。同时,由于协议本身的一些限制,HTTP 协议的传输效率相对较低,因此在一些对效率要求较高的场景下,可能需要使用其他协议替代。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值