linux環境下的一個簡單的web server

來源:互聯網
上載者:User
linux環境下的一個簡單的web server ,可以用來處理靜態http請求。當做socket原理和http的的學習
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#defineFILE_MAX_SIZE100000#define back_log10#define PORT8080#define RECV_SIZE1024#defineSEND_SIZE100000#defineURI_SIZE128
char *get_uri(char *req_header, char *uri_buf){int index = 0;while( (req_header[index] != '/') && (req_header[index] != '\0') ){index++;}int base = index;while( ((index - base) < URI_SIZE) &&(req_header[index]!=' ') && (req_header[index] != '\0') ){index++;}if((req_header[index - 1] == '/') && (req_header[index] == ' ')){strcpy(uri_buf, "index.html");return uri_buf;}strncpy(uri_buf, req_header + base + 1, index - base - 1);return uri_buf;}int http_session(int *connect_fd, struct sockaddr_in *client_addr){char recv_buf[RECV_SIZE + 1];/* server socket receive buffer */unsigned char send_buf[SEND_SIZE + 1];/* server socket send buffer */unsigned char file_buf[FILE_MAX_SIZE + 1];memset(recv_buf, '\0', sizeof(recv_buf));memset(send_buf, '\0', sizeof(send_buf));memset(file_buf, '\0', sizeof(file_buf));char uri_buf[URI_SIZE + 1];/* store the the uri request from client */memset(uri_buf, '\0', sizeof(uri_buf));int res = 0;int read_bytes = 0;int send_bytes = 0;int file_size = 0;        char msg_road[URI_SIZE+1]="/var/www/html/";//change the visit direction      memset(recv_buf, '\0', sizeof(recv_buf));              if( (read_bytes = recv(*connect_fd, recv_buf, RECV_SIZE, 0) ) > 0) {                      memset(uri_buf, '\0', sizeof(uri_buf));                       if(get_uri(recv_buf, uri_buf) == NULL){}              printf("URI:%s\n", uri_buf);                           strcat(msg_road,uri_buf);                           strcpy(uri_buf,msg_road);                      if(access(uri_buf, F_OK)==0&&access(uri_buf, R_OK)==0){  //#define R_OK 4 F_OK 0 .check file           printf("file ok\n");                     }                       printf("\n******************************************\n");         file_size =  get_file(uri_buf, file_buf);                       send_bytes=sizeof(send_buf);                    memcpy(send_buf,file_buf,file_size);                    send(*connect_fd, send_buf, send_bytes, 0);                  }return 0;}int get_file(char *uri_buf, char *file_buf){int read_count = 0;int fd ;if((fd =open(uri_buf, O_RDONLY))==-1){perror("open error in get_file");return -1;}if((read_count = read(fd, file_buf, FILE_MAX_SIZE)) == -1){perror("read error in get_file ");return -1;}return read_count;}int socket_init(int *listen_fd, struct sockaddr_in *server_addr){if((*listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket() error");return -1;}    int opt=1;if(setsockopt(*listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){perror("setsockopt() error");return -1;}  server_addr->sin_family = AF_INET; server_addr->sin_port = htons(PORT); server_addr->sin_addr.s_addr = htonl(INADDR_ANY);if(bind(*listen_fd, (struct sockaddr *)server_addr, sizeof(struct sockaddr_in)) == -1){perror("bind() error.");return -1;}if(listen(*listen_fd, back_log) == -1){perror("listen() error.");return -1;}return 0;}int main(int argc, char *argv[]){int listen_fd;int connect_fd;struct sockaddr_in server_addr;struct sockaddr_in client_addr;        memset(&server_addr, 0,sizeof(struct sockaddr_in));        memset(&server_addr,0, sizeof(struct sockaddr_in));if(socket_init(&listen_fd, &server_addr) == -1){perror("socket_init() error.");exit(1);}socklen_t addrlen = sizeof(struct sockaddr_in);pid_t pid;while(1){if((connect_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &addrlen)) < 0){perror("accept() error");continue;}        pid=fork();if( pid > 0){close(connect_fd);continue;}else if(pid == 0){close(listen_fd);if(http_session(&connect_fd, &client_addr) == -1){perror("http_session() error.");shutdown(connect_fd, SHUT_RDWR); //stop the send and recv in this socketexit(1);/* exit from child process, stop this http session  */}                     shutdown(connect_fd,SHUT_RDWR);                     printf("\nclose connection successfully !\n");exit(0);}else{        exit(1);}}shutdown(listen_fd, SHUT_RDWR);return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.