1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
| #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/select.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h>
int init_listen_socket(short port) { int listen_fd; int ret; struct sockaddr_in server_addr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { fprintf(stderr, "fail to socket : %s\n", strerror(errno)); return -1; }
int on = 1; ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (ret == -1) { perror("set sock reuse addr:"); return -1; }
memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(listen_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)); if (ret < 0) { perror("fail to bind"); return -1; }
listen(listen_fd, 5);
return listen_fd; }
void get_filetype(char *filename, char *filetype) { if (strstr(filename, ".html")) strcpy(filetype, "text/html"); else if (strstr(filename, ".gif")) strcpy(filetype, "image/gif"); else if (strstr(filename, ".png")) strcpy(filetype, "image/png"); else if (strstr(filename, ".jpg")) strcpy(filetype, "image/jpeg"); else strcpy(filetype, "text/plain"); }
int main(int argc, char *argv[]) { int listen_fd; int new_fd; char buf[1024]; char head[1024]; struct stat *file = NULL; char *date = NULL; char filetype[20] = {0}; int ret; FILE *fp; unsigned short port = 8888;
if (argc == 2) { port = strtoul(argv[1], NULL, 10); }
listen_fd = init_listen_socket(port); if (listen_fd == -1) { exit(-1); } printf("listen %d port...\n", port);
while (1) { new_fd = accept(listen_fd, NULL, NULL); if (new_fd < 0) { perror("fail to accept"); break; } printf("Have a new connection!\n");
memset(buf, 0, sizeof(buf)); ret = recv(new_fd, buf, sizeof(buf), 0); if(ret<0){ perror("recv"); }
printf("recv:%s" ,buf); for(int i = 4;;i++) if(buf[i] == 'H'&& buf[i+1] == 'T' && buf[i+2] == 'T' && buf[i+3] == 'P'){ buf[i-1] = 0; break; } char *filename = buf + 5; if(strlen(filename)==0) strcpy(filename, "index.html");
memset(head,0,sizeof(head)); if(strcmp(filename,"health")==0) { filename="health.html"; } fp = fopen(filename ,"rb"); if(NULL == fp){ strcpy(filename, "404.html"); sprintf(head, "HTTP/1.0 404 NOT FOUND\r\n"); fp = fopen(filename ,"rb"); }else sprintf(head, "HTTP/1.0 200 OK\r\n"); fseek(fp, 0, SEEK_END); int len = ftell(fp); if (len <= 0) { fclose(fp); return -1; } fseek(fp, 0, SEEK_SET);
date =(char *)malloc( 0x01 << 24);
len = fread(date, 1, len, fp);
get_filetype(filename, filetype);
sprintf(head, "%sServer: Tiny Web Server\r\n", head); sprintf(head, "%sConnection: close\r\n", head); sprintf(head, "%sContent-length: %d\r\n", head,len); sprintf(head, "%sContent-type: %s\r\n\r\n", head, filetype); printf("Response headers:\n"); printf("%s", head);
ret = send(new_fd, head ,strlen(head) , 0) ; if(ret <0){ perror("send head"); exit(1); } ret = send(new_fd, date ,len , 0) ; if(ret <0){ perror("send date"); exit(1); } free(date); close(new_fd); printf("close connection!\n"); } return 0; }
|