程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> web服務器的實現

web服務器的實現

編輯:C++入門知識

使用c語言實現了一個簡單的web服務器。程序支持html,css,js,jpg,gif格式的請求 [cpp]   #include<stdio.h>   #include<fcntl.h>   #include<netinet/in.h>   #include<arpa/inet.h>   #include<unistd.h>   #include<sys/types.h>   #include<sys/stat.h>   #include<string.h>   #include<stdlib.h>      #define PORT 12345   #define WebRoot /home/meng/webpage   /**   *    * 字符串s1是否以s2結束   */   int endsWith(char s1[],char s2[]){     int len1 = strlen(s1);     int len2 = strlen(s2);     int i=len1-1,j=len2-1;     if(len1<len2)return 0;     for(;i>=0&&j>=0;i--,j--){       if(s1[i]!=s2[j])return 0;     }     return 1;   }   int main(){     int sockfd,fd,client;     struct sockaddr_in addr;     int len=sizeof(addr);     char recbuf[2048];     //socket連接     if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){       perror("socket.\n");       exit(1);     }        //設置IP端口     bzero(&addr,sizeof(addr));          addr.sin_family=AF_INET;     addr.sin_port=htons(PORT);     addr.sin_addr.s_addr=inet_addr("127.0.0.1");        //bind     if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))<0){       perror("bind.\n");       exit(1);     }        //listen 最大連接數     if(listen(sockfd,10)<0){       perror("listen.\n");       exit(1);     }          printf("listening...\n");     while(1){         //取得客戶端的標識         if((client=accept(sockfd,(struct sockaddr*)&addr,&len))<0){             perror("accept.\n");             exit(1);         }         //讀取請求的頭部         int buf=0;         if((buf=read(client,recbuf,2048))>=0){             recbuf[buf]='\0';         }       //printf("%s\n",recbuf);         char *token=strtok(recbuf," ");       //獲得HTTP請求第一行中間部分,也就是URI         if(token!=NULL){             token=strtok(NULL," ");         }       char type[256];       /**       * 根據請求資源結尾的擴展名不同,       * 響應不同mine類型       */       if(endsWith(token,".jpg")){         strcpy(type,"image/jpeg\r\nAccept-Ranges:bytes");       }else if(endsWith(token,".gif")){         strcpy(type,"image/gif");       }else if(endsWith(token,".js")){         strcpy(type,"text/javascript");       }else if(endsWith(token,".css")){         strcpy(type,"text/css");       }else{         strcpy(type,"text/html");       }         //讀取文件內容         char filePath[1024];         char content[2048*512];         int fileSize;         strcpy(filePath,"/home/meng/webpage");         strcat(filePath,token);         fd=open(filePath,O_RDONLY,0766);       if(fd==-1){          strcpy(content,"Not Found");         }else{             fileSize=read(fd,content,sizeof(content));         //printf("%d\n",strlen(content));         content[fileSize]='\0';             if(fileSize<=0)strcpy(content,"Not Found");             close(fd);         }            if(fileSize<=0){             fileSize=strlen("Not Found");         }         char sendBuf[2048*1024];         char tmp[20];         sprintf(tmp,"%d",fileSize);         memset(sendBuf,'\0',sizeof(sendBuf));         //返回HTTP響應的頭部信息       //所有的返回狀態都是200,暫不做404等其它響應狀態的判斷工作         strcat(sendBuf,"HTTP/1.1 200 OK\r\n");         strcat(sendBuf,"Server:MENGXIANLU\r\n");         strcat(sendBuf,"Content-Length:");         strcat(sendBuf,tmp);         strcat(sendBuf,"\r\n");         strcat(sendBuf,"Content-Type: ");       strcat(sendBuf,type);       strcat(sendBuf,"\r\n");       //下面極其重要,表示響應頭部的結束。       //頭部結束後就是正文部分了       strcat(sendBuf,"\r\n");         /** 響應頭部  END */          int i,j;       /** 響應內容(正文)  */       /** 不能使用 strcat進行字符串的連接了。*/       /**如果請求的是圖片,其字節碼中有可能包含'\0'如果使用strcat有可能造成信息的截斷*/       for(i=0,j=strlen(sendBuf);i<fileSize;i++,j++){         sendBuf[j]=content[i];       }       /** 一切准備就緒 */       sendBuf[j]='\0';       /**結果返回給客戶端*/         write(client,sendBuf,j);         close(client);     }     close(sockfd);     return 0;   }     下面是運行程序後,從浏覽器作的一個簡單測試    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved