前面说过,所谓的HTTP协议,只不过是通过端口(一般是80端口)发送HTTP协议的控制字段,再加上网页的内容,即是
html文本。了解了这一点,其实就很容易做一个简单的HTTP服务器,类似于Tomcat的程序。整个过程就是解析浏览器发送过来的请求,然后根据浏览
器的请求,返回对应的html文本即可。
以下程序可以简单实习以上原理,并完成一下功能:
1.可以访问通过浏览器访问本程序文件夹及子文件夹下的文件.
2.对于不存在的文件返回404 NOT FOUND ,存在则返回 HTTP OK
当然,只是一个简单实现,还不具备完整功能。
注
意一点:HTTP协议是基于TPC协议的,而TCP协数据传输议是基于字节流的,但是不要对数据传送和接收的形式做任何假设,网络上的数据不像发送QQ信
息一样,Enter一下就一条,一串字符,可能以任何形式发送到,有可能是整个一串接收到,也有可能是分好几段,也有可能是一个一个字符收到,所以对于数
据的处理要求很高。下面我有两段处理字符的程序,都是用循环实现的,很明显在本机上,只要缓冲区足够大,一般是一次性就收到的,但是实际上网络程序都得仔
细处理收到的数据。
CGI.c
- #include <stdio.h>
-
#include </home/kenvi/program/unpv13e/lib/unp.h>
-
#include "func.h"
-
-
-
int main(int argc,char **argv){
-
int listenfd,connfd;
-
socklen_t len;
-
-
char recvbuf[MAXLINE];
-
char filepath[MAXLINE];//请求的文件路径
-
-
-
-
struct sockaddr_storage cliaddr;
-
-
if(argc!=2)
-
err_quit("usage:cgi1 ");
-
-
listenfd=Tcp_listen(NULL,argv[1],NULL);
-
-
for(;;){
-
len=sizeof(cliaddr);
-
connfd=Accept(listenfd,(SA*)&cliaddr,&len);
-
-
printf("connection from %s\n",Sock_ntop((SA*)&cliaddr,len));
-
bzero(filepath,MAXLINE);
-
int nbyte;
-
int flag=0,n1=0,n2=0,count=0,filetag=0,pathi=0;
-
while((nbyte=Read(connfd,recvbuf,MAXLINE))>0){
-
-
recvbuf[nbyte]='\0';
-
int i;
-
for(i=0;i<nbyte;i++){
-
-
//提取请求文件路径
-
if(filetag==0&&recvbuf[i]==' '&&filepath[0]=='\0') {
-
printf("path started:%d",i);
-
filetag=1;
-
pathi=0;
-
}
-
else if(filetag&&recvbuf[i]==' ')
-
filetag=0;
-
if(filetag){
-
filepath[pathi]=recvbuf[i];
-
pathi++;
-
}
-
//find the crlf
-
if(recvbuf[i]=='\n'){
-
if(n1!=0){
-
n2=n1;
-
n1=i+count;
-
}
-
else{
-
n1=i+count;
-
}
-
-
if(n1==n2+2){
-
flag=1;
-
break;
-
}
-
-
}
-
-
-
}
-
count+=nbyte;
-
filepath[pathi]='\0';
-
if(flag)break;
-
}
-
-
-
getFunc(connfd,(char*)&filepath[2]);
-
Close(connfd);
-
}
-
-
}
func.h
- #ifndef __func_h
-
#define __func_h
-
#include </home/kenvi/program/unpv13e/lib/unp.h>
-
-
#define NOTFOUND "HTTP/1.1 404 Not Found\n\nErrorThe Page You Request Is Not Found."
-
#define OKMSG "HTTP/1.1 200 OK\n\n"
-
-
-
int getFunc(int sockfd,const char *path){
-
printf("%s",path);
-
-
int fd=open(path,O_RDONLY);//只读方式打开
-
char sendbuf[MAXLINE];
-
if(fd<0){
-
Write(sockfd,NOTFOUND,sizeof(NOTFOUND));
-
return 404;//不存在该文件
-
-
}
-
int n;
-
Write(sockfd,OKMSG,sizeof(OKMSG));//发送控制信息
-
-
-
while((n=Read(fd,sendbuf,MAXLINE))>0){
-
Write(sockfd,sendbuf,n);//发送信息
-
-
-
}
-
close(fd);
-
return 200;
-
-
}
-
-
#endif
编译运行。
用浏览器访问127.0.0.1
可以在该程序目录下添加对应文件进行访问。
例如我在目录下编辑好一个index.html
则访问 127.0.0.1/index.html
浏览器可以显示该网页。
阅读(1442) | 评论(0) | 转发(0) |