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

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

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

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

  1. GET / HTTP/1.1
  2. Host: localhost:
  3. Connection: keep-alive
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  5. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
  6. Gecko) Chrome/33.0.1750.154 Safari/537.36
  7. Accept-Encoding: gzip,deflate,sdch
  8. Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

  

  

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

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

  首先写一个html的helloworld

  1. <html>
  2. <head>
  3. <title>welcome</title>
  4. <head>
  5. <body>
  6. <h1>Hello World</h1>
  7. </body>
  8. </html>

  然后再命令行中输入

  1. nc -lp < helloworld.html

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

  

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

  

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

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

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

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

  四、jsp等动态网站的问题

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

  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  3. <html>
  4. <head>
  5. <title>welcome</title>
  6. </head>
  7. <body>
  8. <% String str="<h1>Hello JSP</h1>"; %>
  9. <% out.println(str); %>
  10. </body>
  11. </html>

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

  

  我们可以在tomcat的work目录(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 <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <string.h>
  6. #include <arpa/inet.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  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,,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();
  23.  
  24. if((server_sockfd=socket(PF_INET,SOCK_STREAM,))<)
  25. {
  26. perror("socket");
  27. return -;
  28. }
  29. if(bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<)
  30. {
  31. perror("bind");
  32. return -;
  33. }
  34.  
  35. listen(server_sockfd,);
  36. sin_size=sizeof(struct sockaddr_in);
  37.  
  38. if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<)
  39. {
  40. perror("accept");
  41. return -;
  42. }
  43.  
  44. printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr));
  45. char *pch="<html><h1>Hello World</h1></html>";
  46. len=send(client_sockfd,pch,strlen(pch),);
  47.  
  48. while((len=recv(client_sockfd,buf,BUFSIZ,))>)
  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 ;
  64. }

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

  

  参考资料:

    Nc 下载: http://joncraton.org/blog/46/netcat-for-windows/

    Nc 的使用: http://freetstar.com/use-nc-in-the-linux/

    Http 协议详解: http://blog.csdn.net/gueter/article/details/1524447

    Java版的http服务器: http://blog.csdn.net/yanghua_kobe/article/details/7296156

    C++版的Http服务器: http://www.cppblog.com/kevinlynx/archive/2008/07/30/57521.html

    TCP Socket linux: http://blog.csdn.net/wangyf101/article/details/9790807

  资料下载: http://files.cnblogs.com/wunaozai/%E4%BA%86%E8%A7%A3HTTP%E5%8D%8F%E8%AE%AE%E6%A0%88.zip

  本文链接: http://www.cnblogs.com/wunaozai/p/3733432.html

了解HTTP协议栈(实践篇)的更多相关文章

  1. 基于netty http协议栈的轻量级流程控制组件的实现

    今儿个是冬至,所谓“冬大过年”,公司也应景五点钟就放大伙儿回家吃饺子喝羊肉汤了,而我本着极高的职业素养依然坚持留在公司(实则因为没饺子吃没羊肉汤喝,只能呆公司吃食堂……).趁着这一个多小时的时间,想跟 ...

  2. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

  3. 软件工程(C编码实践篇)学习心得

    孟繁琛 + 原创作品转载请注明出处 + <软件工程(C编码实践篇)>MOOC课程 http://mooc.study.163.com/course/USTC-1000002006 软件工程 ...

  4. CANopen学习——协议栈

    协议,是双方都提前商量好的通讯约定. 例如:发送1代表灯亮,发送0代表灯灭. 但由于只是单bit的0和1在通信时,抗干扰太弱,且多种控制时不能区分,此时扩展一下协议. 例如:  头      地址   ...

  5. 【转】TCP/IP协议栈及OSI参考模型详解

    OSI参考模型 OSI RM:开放系统互连参考模型(open systeminterconnection reference model) OSI参考模型具有以下优点: 简化了相关的网络操作: 提供设 ...

  6. [ZigBee] 16、Zigbee协议栈应用(二)——基于OSAL的无线控制LED闪烁分析(下)

    说在前面:上一篇介绍了无线LED闪烁实现的OSAL部分,本篇介绍如何实现无线数据收发及数据处理: 上一篇是用SI跟着流程查看源码,我个人认为以架构的思维去了解代码能让人更清晰 ::ZMain.c程序入 ...

  7. BLE 蓝牙协议栈开发

    1.由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(1) 2.由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(2) 3.由浅入深,蓝牙4.0/BLE协议栈开发攻略大全(3)

  8. zigbee学习之路(十五):基于协议栈的按键实验

    一.前言 经过上次的学习,相信大家已经初步学会使用zigbee协议进行发送和接受数据了.今天,我们要进行的实验是按键的实验,学会如何在协议栈里实现按键中断. 二.实验功能 在协议栈上实现按键中断,BU ...

  9. zigbee学习之路(十四):基于协议栈的无线数据传输

    一.前言 上次实验,我们介绍了zigbee原理的应用与使用,进行了基于zigbee的串口发送协议,但是上个实验并没有实现数据的收发.在这个实验中,我们要进行zigbee的接受和发送实验. 二.实验功能 ...

随机推荐

  1. isset、empty、var==null、is_null、var===null详细理解

    //isset: 判断变量是否被初始化 //它并不会判断变量是否为空,并且可能用来判断数组中元素是否被定义 //听说在数组用isset与array_key_exists高出4倍 $a = " ...

  2. Delta3D Open Source Engine

    在看<游戏编程精粹6>时看到了这个引擎,彩插7是这个引擎的Editor,我一看就是Qt写的,我太熟悉Qt的界面了,呵呵.Editor非常强悍!有类似3dmax的4个视图 下载这个看下吧,里 ...

  3. DirectX中文手册

    目  录 第一章 DirectX基础(初级篇) 第一节  什么是DirectX 一.什么是DirectX ? 二.DirectX的组成部分 三.关于DirectDraw 四.为什么要使用DirectD ...

  4. KVM虚拟机的创建、管理与迁移

    [日期:2012-06-01] KVM虚拟机管理 一.环境 role         hostname    ip                  OS kvm_server   target   ...

  5. perf之sched

    如果你对你的进程的响应时间极其苛刻,有一天你发现你的进程响应时间变慢了,而恰好这个机器上也有其他的进程在跟你的进程争用CPU,你想看看你的进程被内核调度的情况,那么你需要用perf-sched工具. ...

  6. html锚点定位不准确问题

    问题描述 当顶部固定时,点击锚点,会跳转到锚点以下. <style> #one,#two,#three{ height: 500px; } #top{ position: fixed; h ...

  7. hihocoder 1638:多级并查集

    题目链接 并查集可以用于聚类. import java.io.FileInputStream; import java.io.FileNotFoundException; import java.ut ...

  8. C语言学习笔记 (009) - 对函数的进一步讨论

    一.给main函数传参: # include <stdio.h> int main(int argc,char **argv){ printf(]); ; } 二.指向函数指针变量的定义 ...

  9. CreateThread与_beginthreadex本质区别

    函数功能:创建线程 函数原型: HANDLEWINAPICreateThread( LPSECURITY_ATTRIBUTESlpThreadAttributes, SIZE_TdwStackSize ...

  10. Android开发的16条小经验总结

    Android开发的16条小经验总结,希望对各位搞Android开发的朋友有所帮助. 1. TextView中的getTextSize返回值是以像素(px)为单位的, 而setTextSize()是以 ...