博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
了解HTTP协议栈(实践篇)
阅读量:4586 次
发布时间:2019-06-09

本文共 7560 字,大约阅读时间需要 25 分钟。

  关于http协议的理论知识,我在这里就不详细说明了,具体下面给出的链接有。接下来都是用具体的操作显示的,各位可以结合起来看。

  一、使用nc打开端口,并使用浏览器进行访问 (对应文章中的HTTP协议详解之请求篇)

  nc -lp 8888      #使用nc打开本地的8888端口

  使用浏览器,在地址栏上输入http://localhost:8888 进行访问(提出请求),此时nc界面上就会有得到一个请求的HTTP协议,具体的请求信息如下:

GET / HTTP/1.1Host: localhost:8888Connection: keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/33.0.1750.154 Safari/537.36Accept-Encoding: gzip,deflate,sdchAccept-Language: zh-CN,zh;q=0.8,en;q=0.6

  

  

  请求后nc没有给出回应的话,浏览器会一直在该页面进行等待。如果手动结束nc程序的话,由于没有给出回应信息,浏览器会给出无法访问该页面。

 

  二、nc后面接着一个资源文件(对应文章中的HTTP协议详解之响应篇)

  首先写一个htmlhelloworld

1 2 3 welcome4 5 6 

Hello World

7 8

  然后再命令行中输入

nc -lp 8888 < helloworld.html

  再浏览器中进行访问就可以得到一个页面了

   

  我们打开浏览器的开发工具,chrome浏览器的快捷键是F12,再network中可以看到下面信息

   

  可以看到里面有200 OK这个响应类别号

 

  三、代码实现一个简单的服务器(这里给出一个网上的java实现)

  没有办法,http服务器,就要用到Socket编程,而c++在这一方面又没有具体的标准。所以会有linuxwindows下的不同,不过java在这方面就没有问题了,先给出个java版的尝尝鲜。代码虽然多,但是具体不难理解。

1 import java.io.*;  2 import java.net.ServerSocket;  3 import java.net.Socket;  4   5   6 public class SingleFileHTTPServer extends Thread {  7       8     private byte[] content;  9     private byte[] header; 10     private int port=80; 11      12     private SingleFileHTTPServer(String data, String encoding, 13                 String MIMEType, int port) throws UnsupportedEncodingException { 14         this(data.getBytes(encoding), encoding, MIMEType, port); 15     } 16      17     public SingleFileHTTPServer(byte[] data, String encoding, String MIMEType, int port)throws UnsupportedEncodingException { 18         this.content=data; 19         this.port=port; 20         String header="HTTP/1.0 200 OK\r\n"+ 21             "Server: OneFile 1.0\r\n"+ 22             "Content-length: "+this.content.length+"\r\n"+ 23             "Content-type: "+MIMEType+"\r\n\r\n"; 24         this.header=header.getBytes("ASCII"); 25     } 26      27     public void run() { 28         try { 29             ServerSocket server=new ServerSocket(this.port); 30             System.out.println("Accepting connections on port "+server.getLocalPort()); 31             System.out.println("Data to be sent:"); 32             System.out.write(this.content); 33              34             while (true) { 35                 Socket connection=null; 36                 try { 37                     connection=server.accept(); 38                     OutputStream out=new BufferedOutputStream(connection.getOutputStream()); 39                     InputStream in=new BufferedInputStream(connection.getInputStream()); 40                      41                     StringBuffer request=new StringBuffer(); 42                     while (true) { 43                         int c=in.read(); 44                         if (c=='\r'||c=='\n'||c==-1) { 45                             break; 46                         } 47                         request.append((char)c); 48                          49                     } 50                          51                         //如果检测到是HTTP/1.0及以后的协议,按照规范,需要发送一个MIME首部 52                         if (request.toString().indexOf("HTTP/")!=-1) { 53                             out.write(this.header); 54                         } 55                          56                         out.write(this.content); 57                         out.flush(); 58                      59                 } catch (IOException e) { 60                     // TODO: handle exception 61                 }finally{ 62                     if (connection!=null) { 63                         connection.close(); 64                     } 65                 } 66             } 67              68         } catch (IOException e) { 69             System.err.println("Could not start server. Port Occupied"); 70         } 71     } 72      73     public static void main(String[] args) { 74         try { 75             String contentType="text/plain"; 76             if (args[0].endsWith(".html")||args[0].endsWith(".htm")) { 77                 contentType="text/html"; 78             } 79              80             InputStream in=new FileInputStream(args[0]); 81             ByteArrayOutputStream out=new ByteArrayOutputStream(); 82             int b; 83             while ((b=in.read())!=-1) { 84                 out.write(b); 85             } 86             byte[] data=out.toByteArray(); 87              88             //设置监听端口 89             int port; 90             try { 91                 port=Integer.parseInt(args[1]); 92                 if (port<1||port>65535) { 93                     port=80; 94                 } 95             } catch (Exception e) { 96                 port=80; 97             } 98              99             String encoding="ASCII";100             if (args.length>2) {101                 encoding=args[2];102             }103             104             Thread t=new SingleFileHTTPServer(data, encoding, contentType, port);105             t.start();106             107         } catch (ArrayIndexOutOfBoundsException e) {108              System.out.println("Usage:java SingleFileHTTPServer filename port encoding");109         }catch (Exception e) {110             System.err.println(e);// TODO: handle exception111         }112     }113 }
View Code

 

  四、jsp等动态网站的问题

  在myeclipse中创建一个web工程,然后创建一个index.jsp文件

1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2  3  4    5    welcome 6    7    8     <% String str="

Hello JSP

"; %> 9 <% out.println(str); %>10 11
View Code

  然后部署在tomcat中,在浏览器中访问。

   

  我们可以在tomcatwork目录(D:\tomcat-6.0.18\work\Catalina\localhost\test\org\apache\jsp)下找到一个名字为index_jsp.java的文件。

   

  使用servlet,对jsp文件进行打印输出。具体的原理我也不是很懂,可以看《How Tomcat Works》。不过我想最后还是输出成一个html文件不然在客户端查看源代码怎么会是html呢。

   

  其他的动态语言应该也是这个思路了。

 

  五、图解服务器-客户端连接过程(单服务器)

  

 

六、C++版的Http服务器(Linux Socket)

  在centos 6.4 g++/gcc4.4.7

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 10 int main(int argc,char * argv[])11 {12 int server_sockfd;13 int client_sockfd;14 int len;15 struct sockaddr_in my_addr;16 struct sockaddr_in remote_addr;17 socklen_t sin_size;18 char buf[BUFSIZ];19 memset(&my_addr,0,sizeof(my_addr));20 my_addr.sin_family=AF_INET;21 my_addr.sin_addr.s_addr=INADDR_ANY;22 my_addr.sin_port=htons(8888);23 24 if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)25 {26 perror("socket");27 return -1;28 }29 if(bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)30 {31 perror("bind");32 return -1;33 }34 35 listen(server_sockfd,5);36 sin_size=sizeof(struct sockaddr_in);37 38 if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)39 {40 perror("accept");41 return -1;42 }43 44 printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr));45 char *pch="

Hello World

";46 len=send(client_sockfd,pch,strlen(pch),0);47 48 while((len=recv(client_sockfd,buf,BUFSIZ,0))>0)49 {50 buf[len]='\0';51 printf("%s\n",buf);52 /*53 if(send(client_sockfd,buf,len,0)<0)54 {55 perror("write");56 return -1;57 }58 */59 }60 close(client_sockfd);61 close(server_sockfd);62 63 return 0;64 }
View Code

  该代码还没有实现判断后缀文件,多用户连接,返回的状态码等问题。这个只是一个简单的服务器。如果你对服务器有兴趣可以查看服务器源代码。apache我们看不懂。一个小一点的http总能看懂吧。

  

  参考资料:

    Nc 下载 

    Nc 的使用 

    Http 协议详解 

    Java版的http服务器 

    C++版的Http服务器 

    TCP Socket linux:  

  资料下载: 

  本文链接: 

 

 

转载于:https://www.cnblogs.com/wunaozai/p/3733432.html

你可能感兴趣的文章
电脑自动开机设置教程
查看>>
rpc接口mock平台
查看>>
传感器模块
查看>>
《奇思妙想》人物篇--图灵奖得主概览
查看>>
Azure开发者任务之二:Cloud Service项目添加到ASP.Net Web中
查看>>
2017.2.28 activiti实战--第七章--Spring容器集成应用实例(五)普通表单
查看>>
读书笔记第一章
查看>>
Android 操作SQLite基本用法
查看>>
iis7 发布mvc3 遇到的HTTP错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容...
查看>>
(vue.js)element ui 表单验证 this$refs[formName]validate里面的内容死活不执行
查看>>
启动多个appium服务(同时运行多台设备)
查看>>
Java大数相乘-hdu1063
查看>>
mysql-mmm 部署高可用集群
查看>>
solaris启动过程详解 分类: arm-linux-Ubuntu ...
查看>>
while循环和递归
查看>>
Linux下yum安装Redis
查看>>
.Net 下未捕获异常的处理
查看>>
[机器学习]-Adaboost提升算法从原理到实践
查看>>
AOP概念
查看>>
memset函数详细用法说明【转】
查看>>