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,浏览器请求不成功.。求大神解释一下.不胜感激.

posted @ 2015-10-26 01:30  超超xc  Views(551)  Comments(0Edit  收藏  举报
I suppose,were childrenonec.