简易web服务器系统设计,简单web服务器的设计与实现

1、socket服务器端

intmake_server_socket_q(int,int);

intmake_server_socket(int protnum)

{

returnmake_server_socket_q(protnum,BACKLOG);

}

intmake_server_socket_q(int portnum,int backlog)

{

struct sockaddr_in saddr;

//创建服务器socket

intsock_id;

sock_id=socket(PF_INET, SOCK_STREAM, 0);

if(sock_id==-1)//失败

{

return -1;

}

bzero((void *)&saddr,sizeof(saddr));

saddr.sin_addr.s_addr=htonl(INADDR_ANY);

saddr.sin_port=htons(portnum);

saddr.sin_family=AF_INET;

//绑定

if(bind(sock_id,(struct sockaddr*)&saddr,sizeof(saddr))!=0)

return -1;

//监听

if(listen(sock_id,backlog)!=0)

return -1;

return sock_id;

}

intconnect_to_server(char *host,int portnum)

{

int sock;

struct sockaddr_in servadd;//the number tocall

struct hostent *hp;//used to get number

//

sock = socket(PF_INET,SOCK_STREAM,0);//geta line

if(sock==-1)

return -1;

//清空

bzero(&servadd,sizeof(servadd));

hp = gethostbyname(host);

if(hp==NULL)

return -1;

bcopy( hp->h_addr,(structsockaddr*)&servadd.sin_addr, hp->h_length);

// servadd.sin_addr=htonl(INADDE_ANY);

servadd.sin_port=htons(portnum);

servadd.sin_family=AF_INET;

if(connect(sock,(structsockaddr*)&servadd,sizeof(servadd))!=0)

return -1;

return sock;

}

2、浏览器端

main(intac,char*av[])

{

//socket描述符和accept描述符

int sock,fd;

FILE *fpin;

//保存请求

char request[BUFSIZ];

if(ac==1)

{

fprintf(stderr,"usage:wsportnum\n");

exit(1);

}

sock=make_server_socket(atoi(av[1]));//atoi方法将字符串变成整型

if(sock==-1) exit(2);

while(1)

{

//该函数会阻塞等待客户端请求到达

fd =accept(sock,NULL,NULL);

//只读方式接收请求(文件流)

fpin=fdopen(fd,"r");

//得到请求

fgets(request,BUFSIZ,fpin);

//打印到控制台请求记录

printf("got a call :request =%s",request);

read_til_crnl(fpin);

//处理请求

process_rq(request,fd);

//结束本次请求

fclose(fpin);

}

}

//读取完整的请求

read_til_crnl(FILE*fp)

{

char buf[BUFSIZ];

while(fgets(buf,BUFSIZ,fp)!=NULL&&strcmp(buf,"\r\n")!=0);

}

//处理请求

process_rq(char*rq, int fd)

{

char cmd[BUFSIZ],arg[BUFSIZ];

//创建子进程,如果不是子进程则结束

if (fork()!=0)

return;

strcpy(arg,"./");

if(sscanf(rq,"%s%s",cmd,arg+2)!=2)

return;

if(strcmp(cmd,"GET")!=0)//只能处理静态网页get方式

cannot_do(fd);

else if (not_exist(arg))//请求出错

do_404(arg,fd);

else if (isadir(arg))//判断是否为目录

do_ls(arg,fd);

else if (ends_in_cgi(arg))//是否为cgi程序

do_exec(arg,fd);

else if (ends_in_sh(arg))//是否为sh程序

do_exec_sh(arg,fd);

else

do_cat(arg,fd);

}

//获取头部信息

header(FILE*fp,char*content_type)

{

fprintf(fp,"HTTP/1.0 200OK\r\n");

if(content_type)

fprintf(fp,"Content-type:%s\r\n",content_type);

}

//请求501错误

cannot_do(intfd)

{

FILE *fp =fdopen(fd,"w");

fprintf(fp,"HTTP/1.0 501 NotImplemented\r\n");

fprintf(fp,"Content-type:text/plain\r\n");

fprintf(fp,"\r\n");

fprintf(fp,"Sorry,HTTP 501!\n\n无法处理请求!");

fclose(fp);

}

//请求出错404

do_404(char*item,int fd)

{

FILE *fp=fdopen(fd,"w");

fprintf(fp,"HTTP/1.0 404 NotFound\r\n");

fprintf(fp,"Content-type:text/plain\r\n");

fprintf(fp,"\r\n");

fprintf(fp,"Sorry,HTTP 404!\n\nTheitem you requested: %s \r\nis not found\r\n",item);

fclose(fp);

}

//判断是否为目录

isadir(char*f)

{

struct stat info;

return(stat(f,&info)!=-1&&S_ISDIR(info.st_mode));

}

//不存在

not_exist(char*f)

{

struct stat info;

return (stat(f,&info)==-1);

}

//显示目录下内容

do_ls(char*dir,intfd)

{

FILE *fp;

fp = fdopen(fd,"w");

header(fp,"text/plain;charset=UTF-8");

fprintf(fp,"\r\n");

fflush(fp);

dup2(fd,1);

dup2(fd,2);

close(fd);

execlp("ls","ls","-l",dir,NULL);

perror(dir);

exit(1);

}

//返回文件类型

char*file_type(char *f)//return 'extension' of file

{

char *cp;

if((cp=strrchr(f,'.'))!=NULL)

return cp+1;

return " ";

}

//cgi类型文件

ends_in_cgi(char*f)

{

return(strcmp(file_type(f),"cgi")==0);

}

//执行shell程序

ends_in_sh(char*f)

{

return(strcmp(file_type(f),"sh")==0);

}

do_exec_sh(char*prog,int fd)

{

system(prog);

}//shell

//执行可执行程序cgi

do_exec(char*prog,int fd)

{

FILE *fp;

fp =fdopen(fd,"w");

header(fp,NULL);

fflush(fp);

dup2(fd,1);

dup2(fd,2);

close(fd);

execl(prog,prog,NULL);

perror(prog);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值