设为首页 加入收藏

TOP

Linux 用tcp实现的简单http服务器(一)
2019-07-09 16:10:21 】 浏览:34
Tags:Linux tcp 实现 简单 http 服务器

Linux 用tcp实现的简单http服务器

main.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include "epoll.h"

int main(int argc, char** argv){

  if(argc != 3){
    printf("eg. port resource_path\n");
    exit(1);
  }
  int port = atoi(argv[1]);
  int ret = chdir(argv[2]);
  if(ret == -1){
    perror("chdir error");
    exit(1);
  }
  
  int lfd = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  ret = bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
  if(ret == -1){
    perror("bind err");
    exit(1);
  }
  listen(lfd, 64);

  epoll_run(lfd);
  
}

epoll.h

#define EVENT_MAX 1024

void epoll_run(int lfd);
void do_accept(int lfd, int efd);
void do_read(int cfd, int efd);
int get_line(int sock, char *buf, int size);
void http_get_request(const char* line, int cfd);
void send_respond_head(int cfd, int no, const char* desp, const char* type, long len);
const char *get_file_type(const char *name);
void send_file(int cfd, const char* path);
void disconnect(int cfd, int epfd);
void send_dir(int cfd, const char* path);
void encode_str(char* to, int tosize, const char* from);
void decode_str(char *to, char *from);

epoll.c

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include "epoll.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>

		    

void epoll_run(int lfd){ int efd = epoll_create(EVENT_MAX); if(efd == -1){ perror("epoll_create err"); exit(1); } struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = lfd; int ret = epoll_ctl(efd, EPOLL_CTL_ADD, lfd, &ev); if(ret == -1){ perror("epoll_ctl err"); exit(1); } struct epoll_event evs[EVENT_MAX]; while(1){ ret = epoll_wait(efd, evs, EVENT_MAX, -1); if(ret == -1){ perror("epoll_wait err"); exit(1); } for(int i = 0; i < ret; ++i){ if(evs[i].data.fd == lfd){ do_accept(lfd, efd); } else { do_read(evs[i].data.fd, efd); } } } } void do_read(int cfd, int efd){ char line[1024]; int len = get_line(cfd, line, sizeof(line)); printf("head:%s", line); while(len){ char buf[1024]; len = get_line(cfd, buf, sizeof buf); printf("%s", buf); } if(strncasecmp("get", line, 3) == 0){ http_get_request(line, cfd); disconnect(cfd, efd); } } void http_get_request(const char* line, int cfd){ char method[12] = {0}; char res[1024] = {0}; sscanf(line, "%[^ ] %[^ ]", method, res); // 转码 将不能识别的中文乱码 - > 中文 // 解码 %23 %34 %5f char destr[1024]; decode_str(destr, res); // 处理path /xx // 去掉path中的/ char* file = destr + 1; char fbuf[1024]; if(strcmp(res, "/") == 0){ file = "./"; //getcwd(fbuf, sizeof(fbuf)); //printf("root:[%s]\n", fbuf); // file = fbuf; } struct stat st; printf("file:[%s]\n", file); int ret = stat(file, &st); if(ret == -1){ //todo 404 perror("stat error"); exit(1); } if(S_ISDIR(st.st_mode)){ //di
编程开发网
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Linux 用libevent实现的简单http.. 下一篇hdu 1427 速算24点【暴力枚举】

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }