c-webserver.c
webserver.c:
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> int main(int ac,char * av[]) { int sock,fd; FILE * fpin; char request[BUFSIZ]; if(ac == 1){ fprintf(stderr,"usage:ws portnum\n"); exit(1); } printf("listing portnum is %s",av[1]); sock = make_server_socket(atoi(av[1])); if(sock == -1) exit(2); /* main loop here */ while(1){ /* take a call and buffer it */ fd = accept(sock,NULL,NULL); fpin = fdopen(fd,"r"); /* read request */ fgets(request,BUFSIZ,fpin); printf("got a call:request = %s ",request); read_til_crnl(fpin); /* do what client asks */ process_rq(request,fd); fclose(fpin); } } /*------------read_til_crnl(FILE *)---------------------------------------- *-------------skip over all request info until a CRNL is seen-----------*/ 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) -------------do waht the request asks for and write reply to fd -------------handles request in a new process -------------rq is HTTP command: GET /foo/bar.html HTTP/1.0 */ process_rq(char * rq,int fd) { char cmd[BUFSIZ],arg[BUFSIZ]; /* create a new process and return if not the child */ if(fork() != 0) return; strcpy(arg,"./"); /* precede args with. */ if(sscanf(rq,"%s %s",cmd,arg+2) != 2) return; if(strcmp(cmd,"GET") != 0) 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)) do_exec(arg,fd); else do_cat(arg,fd); } /*---------the reply header thing: allfunctions need one ----------- if content_type is NULL then don't send content type */ header(FILE * fp,char * content_type) { fprintf(fp,"HTTP/1.0 200 OK\r\n"); if(content_type) fprintf(fp,"Content_type:%s\r\n",content_type); } /*---------Simple function first: -------------cannot_do(fd) unimplemented HTTP command ------------and do_404(item,fd) no such object */ cannot_do(int fd) { FILE * fp = fdopen(fd,"w"); fprintf(fp,"HTTP/1.0 501 Not Implemented\r\n"); fprintf(fp,"Content_type:text/plain\r\n"); fprintf(fp,"\r\n"); fprintf(fp,"That command is not yet Implemented"); fclose(fp); } do_404(char * item,int fd) { FILE * fp = fdopen(fd,"w"); fprintf(fp,"HTTP/1.0 404 Not Found\r\n"); fprintf(fp,"Content_type:text/plain\r\n"); fprintf(fp,"\r\n"); fprintf(fp,"The item you requested:%s\r\n is not found \r\n",item); fclose(fp); } /*-------------the directory listing section ---------------isaddir() uses stat, not_exist() uses stat ---------------do_ls runs ls. It should not */ 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,int fd) { FILE * fp; fp = fdopen(fd,"w"); fprintf(fp,"text/plain\r\n"); fflush(fp); dup2(fd,1); dup2(fd,2); close(fd); execlp("ls","ls","-l",dir,NULL); perror(dir); exit(1); } /*---------the cgi sutff. function to check extension and one to run the program. */ char * file_type(char *f) /* returns 'extension' of file */ { char * cp; if((cp = strrchr(f,'.')) != NULL) return cp+1; return ""; } ends_in_cgi(char *f) { return (strcmp(file_type(f),"cgi") == 0); } 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); } /*------------------do_cat(filename,fd) --------------------send back contents afet a header */ do_cat(char *f,int fd) { char * extension = file_type(f); char * content = "text/plain"; FILE * fpsock, * fpfile; int c; if(strcmp(extension,"html") == 0 ) content = "text/html"; else if(strcmp(extension,"gif") == 0) content = "text/gif"; else if(strcmp(extension,"jpg") == 0) content = "text/jpeg"; else if(strcmp(extension,"jpeg") == 0) content = "text/jpeg"; fpsock = fdopen(fd,"w"); fpfile = fopen(f,"r"); if(fpsock != NULL && fpfile != NULL) { header(fpsock,content); fprintf(fpsock,"\r\n"); while((c = getc(fpfile)) != EOF) putc(c,fpsock); fclose(fpfile); fclose(fpsock); } exit(0); }
socklib.c :
/* socklib.c * This file contains functions used lots when writing internet Client/Server programs. The two main function here are: * -------int make_server_socket(portnum) return a server socket or -1 if error * -------int make_server_socket_q(portnum,backlog) * -------int connect_to_server(char * hostname,int portnum) return a connected socket or -1 if error */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <time.h> #include <strings.h> #define HOSTLEN 256 #define BACKLOG 1 int make_server_socket_q(int,int); int make_server_socket(int portnum) { return make_server_socket_q(portnum,BACKLOG); } int make_server_socket_q(int portnum,int backlog) { struct sockaddr_in saddr; /* build our address here */ struct hostent * hp; /* this is part of our */ char hostname[HOSTLEN]; /* address */ int sock_id; /* the socket */ sock_id = socket(PF_INET,SOCK_STREAM,0); /* get a socket */ if(sock_id == -1) return -1; /* build address andbind it to socket */ bzero((void *)&saddr,sizeof(saddr)); /* clear out struct */ gethostname(hostname,HOSTLEN); /* where am I ? */ hp = gethostbyname(hostname); /* get infoabout host fill in host part */ bcopy((void *)hp -> h_addr,(void *)&saddr.sin_addr,hp->h_length); saddr.sin_port = htons(portnum); /* fill in socket port */ saddr.sin_family = AF_INET; /* fill in addr family */ if(bind(sock_id,(struct sockaddr *)&saddr,sizeof(saddr)) != 0) return -1; /* arrange for incoming calls */ if(listen(sock_id,backlog) != 0) return -1; return sock_id; } int connect_to_server(char * host,int portnum) { int sock; struct sockaddr_in servadd; /* the number to call */ struct hostent *hp; /* used to get number */ /* step 1 : GEt a socket */ sock = socket(AF_INET,SOCK_STREAM,0); if(sock == -1) return -1; /* Step 2: connect to server */ bzero(&servadd,sizeof(servadd)); /* zero the address */ hp = gethostbyname(host); /* lookup host's ip # */ if(hp == NULL) return -1; bcopy(hp->h_addr,(struct sockaddr *)&servadd.sin_addr,hp->h_length); servadd.sin_port = htons(portnum); /* fill in port number */ servadd.sin_family = AF_INET; /* fill in socket type */ if(connect(sock,(struct sockaddr *)&servadd,sizeof(servadd)) != 0) return -1; return sock; }
编译:gcc webserver.c socklib.c -o webserv
运行:./webserv 8000
问题:,,运行没问题,但是socket()返回0,浏览器请求不成功.。求大神解释一下.不胜感激.