首页 > 代码库 > Linux_C socket 服务器(cat ,execl功能)
Linux_C socket 服务器(cat ,execl功能)
客户端和web服务器交互的基本结构如下:
(1)客户端发送请求
GET filename HTTP/version
可选参数
空行
(2)服务器发送应答
HTTP/version status-code status-message
附加信息
空行
内容
webserv.c
1 /* webserv.c a minimal web server (version 0.2) 2 * usage : webserv portnumber 3 */ 4 #include <stdio.h> 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <string.h> 8 #include <sys/stat.h> 9 #include <netinet/in.h> 10 #include <netdb.h> 11 12 int make_server_socket(int); 13 14 int main(int argc, char* argv[]) { 15 int sock, fd; 16 FILE * fpin; 17 char request[BUFSIZ]; 18 19 if(argc==1) { 20 fprintf(stderr , "usage :webserv portnum.\n"); 21 exit(1); 22 } 23 sock=make_server_socket(atoi(argv[1])); 24 if(sock==-1) 25 exit(2); 26 while(1) { 27 /* take a call and buffer it */ 28 fd=accept(sock, NULL, NULL); 29 fpin=fdopen(fd, "r"); 30 /* read request */ 31 fgets(request, BUFSIZ, fpin); 32 printf("get a call ; request = %s", request); 33 read_til_crnl(fpin); 34 /* do what client asks */ 35 process_rq(request, fd); 36 37 fclose(fpin); 38 } 39 return 0; 40 } 41 42 int make_server_socket(int portnum) { 43 int sock; 44 struct sockaddr_in saddr; 45 struct hostent *hp; 46 char hostname[BUFSIZ]; 47 48 sock=socket(PF_INET, SOCK_STREAM, 0); 49 if(sock==-1) 50 return -1; 51 52 gethostname(hostname, BUFSIZ); 53 hp=gethostbyname(hostname); 54 bzero(&saddr, sizeof(saddr)); 55 bcopy((void*)hp->h_addr, (void*)&saddr.sin_addr, hp->h_length); 56 saddr.sin_port=htons(portnum); 57 saddr.sin_family=AF_INET; 58 59 if(bind(sock, (struct sockaddr*)&saddr, sizeof(saddr))!=0) 60 return -1; 61 if(listen(sock ,1)!=0) 62 return -1; 63 return sock; 64 } 65 66 /********************************************************************** 67 * read_til_crnl(FILE* ) 68 * skip over all request info until a CRNL is seen 69 *********************************************************************/ 70 read_til_crnl(FILE* fp) { 71 char buf[BUFSIZ]; 72 while(fgets(buf, BUFSIZ, fp)!=NULL && strcmp(buf, "\r\n")!=0) 73 ; 74 } 75 76 /********************************************************************* 77 * process_rq(char* rq, int fd) 78 * do what the request asks for and write reply to fd 79 * handles request in a new process 80 * rq is HTTP command: GET /foo/bar.html HTTP/1.0 81 ********************************************************************/ 82 process_rq(char *rq, int fd) { 83 char cmd[BUFSIZ], arg[BUFSIZ]; 84 /*creat a new process and return if not the child*/ 85 if(fork()!=0) 86 return ; 87 strcpy(arg, "./"); /* precede args with .*/ 88 if(sscanf(rq, "%s %s", cmd, arg+2)!=2) 89 return ; 90 if(strcmp(cmd, "GET")!=0) 91 cannot_do(fd); 92 else if(not_exist(arg)) 93 do_404(arg, fd); 94 else if(isadir(arg)) 95 do_ls(arg, fd); 96 else if(ends_in_cgi(arg)) 97 do_exec(arg, fd); 98 else 99 do_cat(arg, fd);100 }101 102 103 104 /*********************************************************105 * the reply header thing: all functions need one106 * if content_type is NULL then don‘t send content type107 ********************************************************/108 header(FILE* fp, char * content_type) {109 fprintf(fp, "HTTP/1.0 200 OK\r\n");110 if(content_type)111 fprintf(fp, "Content-type: %s\r\n", content_type);112 }113 114 /********************************************************* 115 * simple functions first:116 * cannot_do(fd): unimplemented HTTP command117 * and do_404*(item ,fd) no such object118 ********************************************************/119 120 cannot_do(fd) {121 FILE *fp=fdopen(fd, "w");122 123 fprintf(fp, "HTTP/1.0 501 Not Implemented\r\n");124 fprintf(fp, "Content-type: text/plain\r\n");125 fprintf(fp, "\r\n");126 127 fprintf(fp, "That command is not yet implemented\r\n");128 fclose(fp);129 }130 131 do_404(char* item, int fd) {132 FILE* fp=fdopen(fd, "w");133 134 fprintf(fp, "HTTP/1.0 404 Not Found\r\n");135 fprintf(fp, "Content-type:text/plain\r\n");136 fprintf(fp, "\r\n" );137 138 fprintf(fp, "The item you requested: %s\r\nis not found\r\n", item);139 fclose(fp);140 }141 142 /******************************************************************143 * the directory listing sectoin144 * isadir() uses stat, not_exist() uses stat145 * do_ls runs ls. It should not146 *****************************************************************/147 148 isadir(char *f) {149 struct stat info;150 return (stat(f, &info)!=-1 && S_ISDIR(info.st_mode));151 }152 153 not_exist(char *f) {154 struct stat info;155 return (stat(f, &info)==-1);156 }157 158 do_ls(char *dir, int fd) {159 FILE* fp;160 fp=fdopen(fd, "w");161 header(fp, "text/plain");162 fprintf(fp, "\r\n");163 fflush(fp);164 165 dup2(fd, 1);166 dup2(fd, 2);167 close(fd);168 execlp("ls", "ls", "-l",dir, NULL);169 perror(dir);170 exit(1);171 }172 173 /*******************************************************174 * the cgi stuff function to check extension and175 * one to run the program.176 ******************************************************/177 char * file_type(char* f) {178 /* returns ‘extension‘ of file */179 char *cp;180 if((cp=strrchr(f, ‘.‘))!=NULL)181 return cp+1;182 return "";183 }184 185 ends_in_cgi(char* f) {186 return (strcmp(file_type(f) , "cgi")==0);187 }188 189 do_exec(char *prog, int fd) {190 FILE *fp;191 192 fp=fdopen(fd, "w");193 header(fp, NULL);194 fflush(fp);195 dup2(fd, 1);196 dup2(fd, 2);197 close(fd);198 execl(prog, prog, NULL);199 perror(prog);200 }201 202 /*******************************************************************203 * do_cat(filename, fd)204 * sends back contents after a header205 ******************************************************************/206 do_cat(char* f, int fd) {207 char *extension = file_type(f);208 char *content = "text/plain";209 FILE *fpsock, *fpfile;210 int c;211 212 if(strcmp(extension, "html")==0)213 content = "text/html";214 else if(strcmp(extension, "gif")==0)215 content = "image/gif";216 else if(strcmp(extension, "jpg")==0)217 content = "image/jpeg";218 else if(strcmp(extension, "jpeg")==0)219 content = "image/jpeg";220 221 fpsock = fdopen(fd, "w");222 fpfile = fopen(f, "r");223 if(fpsock != NULL && fpfile!=NULL) {224 header(fpsock, content);225 fprintf(fpsock, "\r\n");226 while((c=getc(fpfile))!=EOF)227 putc(c, fpsock);228 fclose(fpfile);229 fclose(fpsock);230 }231 exit(0);232 }
Linux_C socket 服务器(cat ,execl功能)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。