了解HTTP协议栈(实践篇)

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

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

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

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


GET / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/33.0.1750.154 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
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>

  然后再命令行中输入

 nc -lp 8888 < 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
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 exception
111 }
112 }
113 }

  四、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,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="<html><h1>Hello World</h1></html>";
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 }

  该代码还没有实现判断后缀文件,多用户连接,返回的状态码等问题。这个只是一个简单的服务器。如果你对服务器有兴趣可以查看服务器源代码。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协议栈(实践篇),布布扣,bubuko.com

时间: 2024-10-13 07:35:32

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

OSI模型和TCP/IP协议栈

OSI(Open System Interconnect )开放系统互连参考模型是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架.这里所说的开放系统,实质上指的是遵循OSI参考模型和相关协议能够实现互连的具有各种应用目的的计算机系统.它从低到高分别是:物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.而TCP/IP协议栈和OSI模型有着对应关系,那么先看一下OSI参考模型.OSI参考模型如下图所

TCP/IP协议栈

TCP/IP协议栈全称是传输控制协议/因特网互联协议,其实是OSI模型的进化版,所以就先解释一下什么是OSI模型,OSI的全称是开放系统互连参考模型,就是为了实现开放系统互连所建立的通信功能分层模型,其目的就是为异种计算机互连提供一个共同的基础和标准框架,并为保持相关标准的一致性和兼容性提供共同的参考.这里的开放系统指的是遵循OSI模型和相关协议能够实现互连的具有各种应用目的的计算机系统.OSI模型一共有七层,TCP模型一共只有四层,分别为应用层,传输层,Internet层,网络访问层.它定义了

TCP/IP协议栈模型

OSI七层模型介绍: 下面4层(物理层.数据链路层.网络层和传输层)主要提供数据传输和交换功能,即以节点到节点之间的通信为主:第4层作为上下两部分的桥梁,是整个网络体系结构中最关键的部分:而上3层(会话层.表示层和应用层)则以提供用户与应用程序之间的信息和数据处理功能为主. 物理层的主要功能是:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输,尽可能屏蔽掉具体传输介质和物理设备的差异. 数据链路层主要功能:建立和管理节点间的链路.通过各种控制协议,通过差错控制.流量控制方法,将有差错的

LwIP - raw/callback API、协议栈API(sequential API)、BSD API(或者说 SOCKET API)

1.使用raw/callback API编程,用户编程的方法是向内核注册各种自定义的回调函数,回调函数是与内核实现交换的唯一方式. recv_udp, accept_function, sent_tcp, recv_tcp, do_connected, poll_tcp, err_tcp! 2.协议栈API(sequential API)是基于raw/callback API实现的,它与内核交换的方式也只能通过回调. netconn_new, netconn_delete, netconn_ge

高级软件工程(C编码实践篇)--心得

吴松泽 + 原创作品转载请注明出处 + <软件工程(C编码实践篇)>MOOC课程http://mooc.study.163.com/course/USTC-1000002006 1.心得体会: 跟随孟宁老师学习了软件工程mooc这门课程,不但让我从理论上掌握软件工程,还有从不同的实例,让理论和实践得到了很好的结合.整一个学期下来,总的来说还是学到了很多东西的,有很多地方是值得肯定的,其实在我看来,软件工程与其说是一门课程,不如说是一门思想.是一个如何去分析和处理问题的过程,应该说其范畴已经远远

BLE 蓝牙协议栈开发

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

蓝牙利用协议栈API读取设备MAC地址

最近在移植QQ物联协议,需要读取设备mac地址. 读取CC2541设备MAC地址的方法,有直接读取mac寄存器,也可以调用协议栈API.这里采用的是调用API的形式. 1 /*利用协议栈API读取MAC地址*/ 2 static uint8 macaddr[B_ADDR_LEN]={0}; // mac 地址 3 uint8_t macstr[13] = {0}; 4 5 GAPRole_GetParameter(GAPROLE_BD_ADDR, macaddr); 6 sprintf((cha

windows下重新安装TCP/IP协议栈

一.windows重装TCP/IP协议     前两天在windows下安装开发环境的时候,把系统的TCP/IP协议栈给搞跪了,导致系统无法ping localhost.无法在程序中创建socket等....于是对windows 7(64bit)下的TCP/IP协议栈进行了重装.尝试了很多方法,发现一个可以使用的: (1)删除注册表键值     开始——运行——regedit,找到 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Wins

Linux下TCP/IP协议栈的简单脉络分析

最近在写网络编程方面的一些东西,然后遇到了关于传输上的小问题.由于之前有简单的看过一些TCP/IP详解的一些东西,所以索性就找了本<追踪LinuxTCP/IP代码运行>的书看了一上午,结果发现初次接触这些内核方面的东西,收获甚微.于是又在网上找相关类的大神博客,拿来拜读,虽然依然看的不是太明白,吸收的也不够好,但是我想以博客的形式把它记录下来,也希望能为我以后学这些东西开个好头吧 1.linux的网络协议栈的主要结构 (1)socket层 这层主要处理socket相关的东西,例如其各种结构的初