http 是封裝在tcp上的一個數據報文html
#include<sys/socket.h> #include<errno.h> #include<netinet/in.h> #include<string.h> #include<stdio.h> #define BUF_LEN 1028 #define SERVER_PORT 8080 //定義好的html頁面,實際狀況下web server基本是從本地文件系統讀取html文件 const static char http_error_hdr[] = "HTTP/1.1 404 Not Found\r\nContent-type: text/html\r\n\r\n"; const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n"; const static char http_index_html[] = "<html><head><title>Congrats!</title></head>" "<body><h1>Welcome to our HTTP server demo!</h1>" "<p>This is a just small test page.</body></html>"; //解析到HTTP請求的文件後,發送本地文件系統中的文件 //這裏,咱們處理對index文件的請求,發送咱們預約好的html文件 //呵呵,一切從簡! int http_send_file(char *filename, int sockfd) { if(!strcmp(filename, "/")){ //經過write函數發送http響應報文;報文包括HTTP響應頭和響應內容--HTML文件 write(sockfd, http_html_hdr, strlen(http_html_hdr)); write(sockfd, http_index_html, strlen(http_index_html)); } else{ // 文件未找到狀況下發送404error響應 printf("%s:file not find!\n",filename); write(sockfd, http_error_hdr, strlen(http_error_hdr)); } return 0; } //HTTP請求解析 void serve(int sockfd){ char buf[BUF_LEN]; read(sockfd, buf, BUF_LEN); if(!strncmp(buf, "GET", 3)){ char *file = buf + 4; char *space = strchr(file, ' '); *space = '\0'; http_send_file(file, sockfd); } else{ //其餘HTTP請求處理,如POST,HEAD等 。這裏咱們只處理GET printf("unsupported request!\n"); return; } } void main(){ int sockfd,err,newfd; struct sockaddr_in addr; //創建TCP套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0){ perror("socket creation failed!\n"); return; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; //這裏要注意,端口號必定要使用htons先轉化爲網絡字節序,不然綁定的實際端口 //可能和你須要的不一樣 addr.sin_port = htons(SERVER_PORT); addr.sin_addr.s_addr = INADDR_ANY; if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))){ perror("socket binding failed!\n"); return; } listen(sockfd, 128); for(;;){ //不間斷接收HTTP請求並處理,這裏使用單線程,在實際狀況下考慮到效率通常多線程 newfd = accept(sockfd, NULL, NULL); serve(newfd); close(newfd); } }