Chinaunix首页 | 论坛 | 博客
  • 博客访问: 622015
  • 博文数量: 69
  • 博客积分: 1891
  • 博客等级: 上尉
  • 技术积分: 1359
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-20 23:38
文章分类

全部博文(69)

文章存档

2012年(46)

2011年(23)

分类: C/C++

2011-05-24 01:49:46

前面说过,所谓的HTTP协议,只不过是通过端口(一般是80端口)发送HTTP协议的控制字段,再加上网页的内容,即是 html文本。了解了这一点,其实就很容易做一个简单的HTTP服务器,类似于Tomcat的程序。整个过程就是解析浏览器发送过来的请求,然后根据浏览 器的请求,返回对应的html文本即可。

以下程序可以简单实习以上原理,并完成一下功能:

1.可以访问通过浏览器访问本程序文件夹及子文件夹下的文件.

2.对于不存在的文件返回404 NOT FOUND ,存在则返回 HTTP OK

当然,只是一个简单实现,还不具备完整功能。

注 意一点:HTTP协议是基于TPC协议的,而TCP协数据传输议是基于字节流的,但是不要对数据传送和接收的形式做任何假设,网络上的数据不像发送QQ信 息一样,Enter一下就一条,一串字符,可能以任何形式发送到,有可能是整个一串接收到,也有可能是分好几段,也有可能是一个一个字符收到,所以对于数 据的处理要求很高。下面我有两段处理字符的程序,都是用循环实现的,很明显在本机上,只要缓冲区足够大,一般是一次性就收到的,但是实际上网络程序都得仔 细处理收到的数据。


CGI.c

  1. #include <stdio.h>
  2. #include </home/kenvi/program/unpv13e/lib/unp.h>
  3. #include "func.h"


  4. int main(int argc,char **argv){
  5.     int listenfd,connfd;
  6.     socklen_t len;
  7.    
  8.     char recvbuf[MAXLINE];
  9.     char filepath[MAXLINE];//请求的文件路径



  10.     struct sockaddr_storage cliaddr;

  11.     if(argc!=2)
  12.         err_quit("usage:cgi1 ");

  13.     listenfd=Tcp_listen(NULL,argv[1],NULL);

  14.     for(;;){
  15.         len=sizeof(cliaddr);
  16.         connfd=Accept(listenfd,(SA*)&cliaddr,&len);

  17.         printf("connection from %s\n",Sock_ntop((SA*)&cliaddr,len));
  18.         bzero(filepath,MAXLINE);
  19.         int nbyte;
  20.         int flag=0,n1=0,n2=0,count=0,filetag=0,pathi=0;
  21.         while((nbyte=Read(connfd,recvbuf,MAXLINE))>0){

  22.             recvbuf[nbyte]='\0';
  23.             int i;
  24.             for(i=0;i<nbyte;i++){

  25.   //提取请求文件路径
  26.             if(filetag==0&&recvbuf[i]==' '&&filepath[0]=='\0') {
  27.                             printf("path started:%d",i);
  28.                             filetag=1;
  29.                             pathi=0;
  30.             }
  31.             else if(filetag&&recvbuf[i]==' ')
  32.                             filetag=0;
  33.             if(filetag){
  34.                             filepath[pathi]=recvbuf[i];
  35.                             pathi++;
  36.             }
  37.                 //find the crlf
  38.                 if(recvbuf[i]=='\n'){
  39.                     if(n1!=0){
  40.                         n2=n1;
  41.                         n1=i+count;
  42.                     }
  43.                     else{
  44.                         n1=i+count;
  45.                     }

  46.                     if(n1==n2+2){
  47.                         flag=1;
  48.                         break;
  49.                     }

  50.                 }


  51.             }
  52.             count+=nbyte;
  53.             filepath[pathi]='\0';
  54.             if(flag)break;
  55.   }


  56.         getFunc(connfd,(char*)&filepath[2]);
  57.         Close(connfd);
  58.   }

  59. }


func.h


  1. #ifndef __func_h
  2. #define __func_h
  3. #include </home/kenvi/program/unpv13e/lib/unp.h>

  4. #define NOTFOUND "HTTP/1.1 404 Not Found\n\nErrorThe Page You Request Is Not Found."
  5. #define OKMSG "HTTP/1.1 200 OK\n\n"


  6. int getFunc(int sockfd,const char *path){
  7.     printf("%s",path);

  8.     int fd=open(path,O_RDONLY);//只读方式打开
  9.     char sendbuf[MAXLINE];
  10.     if(fd<0){
  11.         Write(sockfd,NOTFOUND,sizeof(NOTFOUND));
  12.         return 404;//不存在该文件

  13.     }
  14.     int n;
  15.     Write(sockfd,OKMSG,sizeof(OKMSG));//发送控制信息


  16.     while((n=Read(fd,sendbuf,MAXLINE))>0){
  17.         Write(sockfd,sendbuf,n);//发送信息


  18.     }
  19.     close(fd);
  20.     return 200;

  21. }

  22. #endif

编译运行。

用浏览器访问127.0.0.1

可以在该程序目录下添加对应文件进行访问。

例如我在目录下编辑好一个index.html

则访问 127.0.0.1/index.html


浏览器可以显示该网页。
阅读(1442) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~