关于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