浅谈http协议(如何TCP实现HTTP)

Posted 生活黑科技分享

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈http协议(如何TCP实现HTTP)相关的知识,希望对你有一定的参考价值。

浅谈http协议(如何TCP实现HTTP)

前言

上一期的题在这里不解答了,最后演变的局势是一个马后炮绝杀。而本期将进入技术篇——浅谈http协议。

正文

首先我们需要抓取http协议包,一般说到抓包,很多人会想到用抓包工具,如fiddler、wireshark等。这些工具确实不错,不过本文在这里不采用抓包工具,而是用另外一些工具进行“抓包”,在这将介绍两中“抓包”方法。

第一种是直接用浏览器,开发过网页的人都知道在浏览器窗口按下F12则可以进入开发者工具。我们登录韩师官网为例,即:http://www.hstc.edu.cn/,为了方便和post请求区分,我们在网址内加个参数,即:http://www.hstc.edu.cn?action=test,然后进入控制台的network:

浅谈http协议(如何TCP实现HTTP)

可以看出浏览器把请求分为两部分,即请求标头和请求正文(其实还可以细分的,我们在另一个方式下将对请求在进行细分),这里就出现一个很奇葩的现象了,请求正文是空的?按照道理来讲请求正文应该是“action=test”才对。然后仔细观看,在请求标头里出现“GET /? action=test”。然后我们去抓一下post请求:

浅谈http协议(如何TCP实现HTTP)

浅谈http协议(如何TCP实现HTTP)

这样,真相也就出来了,请求正文是post请求的参数,无论是文件流还是键值对,都将在这实现。

然后,来谈谈第二种方式,本文着重要讲的就是这种方式。大家都知道http是基于tcp协议的,但是在浏览器上你根本就不知道怎么通过tcp协议封装的,很多开发人员也是局限在这里,根本就不知道什么是http协议。如果你清楚了解http协议,你可以做很多事情,比如自己实现上期的代理服务器(CCPROXY)。为了让读者们清楚了解http协议,我们打开网络调试助手,开启一个8088端口。然后在浏览器上访问http://192.168.0.107:8088

浅谈http协议(如何TCP实现HTTP)

而两个回车(如果是get请求一定要加上\r\n\r\n,否则将不能作为http请求发送),分别对应请求空行和请求正文,无论是get请求还是post请求,它都一样一样是这样的格式。测试中我们可以发现,浏览器一直加载,知道超时出错。这个时候就需要响应的格式了,响应格式如下

浅谈http协议(如何TCP实现HTTP)

其中http的响应吗主要可以分为以下几类:

浅谈http协议(如何TCP实现HTTP)

然后我们继续试验,当浏览器发送请求后,我们按照响应格式,回应如下

浅谈http协议(如何TCP实现HTTP)

然后浏览器响应如下

浅谈http协议(如何TCP实现HTTP)

然后我们再测试下响应码为302的重定向,让其重定向到韩师主页,两个回车记得加上。

浅谈http协议(如何TCP实现HTTP)


然后,浏览器就定向到韩师了。

浅谈http协议(如何TCP实现HTTP)

那么我们如何模拟http请求来访问韩师主页呢?同样我们先进行“抓包”,读者估计还是一下子想到用抓包工具进行抓包,但本文还是不采用抓包工具,我们使用上两期教大家的方法,把http://192.168.0.107:8088/作为代理服务器,设置完成后我们来访问以下韩师官网http://www.hstc.edu.cn/,然后我们可以收到如下数据

浅谈http协议(如何TCP实现HTTP)

浅谈http协议(如何TCP实现HTTP)

至此,最基本的的http协议已通过TCP协议初步实现的方法。当然http协议还有很多规范,具体可以查阅下相关资料。深入了解http协议后你可以很多事情,例如教务系统外网登录,实现起来原理也简单,只需要将内网服务器映射到外网,外网即可通过内网访问教务系统。原理上和上两期的内容差不多。你也可以实现短信轰炸机等等多数和http有关的事情。在这里,给大家实现一下上两期的代理服务器。

主要实现的是线程的函数,线程函数如下:

public void run() {
   String line;
   String host;
  
int port=80;
   Socket outbound=
null;
  
try {
     
socket.setSoTimeout(TIMEOUT);
      InputStream is=
socket.getInputStream();
      OutputStream os=
null;
     
try {
        
line="";
         host=
"";
        
int state=0;
        
boolean space;
        
while (true) {
           
int c=is.read();
           
if (c==-1) break;;
            space=Character.isWhitespace((
char)c);
           
switch (state) {
              
case 0:
                 
if (space) continue;
                  state=
1;
              
case 1:
                 
if (space) {
                     state=
2;
                     
continue;
                  }
                  line=line+(
char)c;
                 
break;
              
case 2:
                 
if (space) continue;
                  state=
3;
              
case 3:
                 
if (space) {
                     state=
4;
                     String host0=host;
                    
int n;
                     n=host.indexOf(
"//");
                    
if (n!=-1) host=host.substring(n+2);
                     n=host.indexOf(
'/');
                    
if (n!=-1) host=host.substring(0,n);
                     n=host.indexOf(
":");
                    
if (n!=-1) {
                        port=Integer.parseInt(host.substring(n+
1));
                        host=host.substring(
0,n);
                     }
                     host=processHostName(host0,host,port,
socket);
                    
int retry=CONNECT_RETRIES;
                    
while (retry--!=0) {
                       
try {
                           outbound=
new Socket(host,port);
                          
break;
                        }
catch (Exception e) { }
                        Thread.sleep(
CONNECT_PAUSE);
                     }
                    
if (outbound==null) break;
                     outbound.setSoTimeout(
TIMEOUT);
                     os=outbound.getOutputStream();
                     os.write(line.getBytes());
                     os.write(
' ');
                     os.write(host0.getBytes());
                     os.write(
' ');
                    
break;
                  }
                  host=host+(
char)c;
                 
break;
            }
         }
      }
     
catch (IOException e) { }

   }
catch (Exception e) { }
  
finally {
     
try { socket.close();} catch (Exception e1) {}
     
try { outbound.close();} catch (Exception e2) {}
   }
}

然后我们用Intellij Idea执行一下

 

浅谈http协议(如何TCP实现HTTP)

然后访问http://www.hstc.edu.cn/,完美成功。

 

浅谈http协议(如何TCP实现HTTP)

至此,http讲解结束,感兴趣的可以跟笔者要代理服务器源码,至于https就由读者自己去分析和实现了。

PC端全局实现

前两期中,有读者问我,电脑如何让QQ、微信等实现代理上网,鉴于读者需求还是有点多,在这里将教大家实现。笔者推荐两种方式,一个是SocksCap,这个软件得自己实现分应用共享上网,感兴趣可以自己去弄一下。这里主要介绍另一种也就是proxifier,不过很遗憾,官网http://www.proxifier.com/得科学上网后才能访问。

浅谈http协议(如何TCP实现HTTP)

安装包在此处链接:https://pan.baidu.com/s/1f7uRR1GfG8wGDCubmBlbpQ 密码:6dca

浅谈http协议(如何TCP实现HTTP)

浅谈http协议(如何TCP实现HTTP)

结束语

最后进入每日一题活动,你觉得http/https协议安全么?如果不安全,如何实现安全上网?


以上是关于浅谈http协议(如何TCP实现HTTP)的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Http和TCP

浅谈HTTP中GET和POST请求方式的区别

浅谈HTTP(简) TCP协议

浅谈Http协议与TCP/IP协议

浅谈HTTP协议

浅谈QUIC协议原理与性能分析及部署方案