<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一個簡單的HTTP服務器的實現

      我們繼續我們的HTTP服務器的實現(使用別的代碼來實現),
      這個HTTP服務器的實現,我們主要就是關注TCP服務器中的recv還有send的處理。
      首先,看一下HTTP,我們在用瀏覽器訪問我們的TCPserver的時候,會收到什么樣的請求。

      這是直接訪問端口的時候,返回的數據,我們在隨便輸入一個地址測試一下。

      可以發現一個特點,就是我們在當訪問http://192.168.149.131:8888/get的時候,可以得到/get,因此我們在接受到請求的時候,就可以進行第一行的解析,

      int readline(char* allbuf,int idx,char * linebuf){
      	int len=strlen(allbuf);
      
      	for (idx < len; idx++)
      	{
      		/* code */
      		if (;allbuf[idx]=='\r'||allbuf[idx+1]=='\n')
      		{
      			return idx+2;
      		}else{
      			*(linebuf++)=allbuf[idx];
      		}
      		
      	}
      	
      }
      

      然后就是開始定義我們一些需要的結構體之類的

      #define BUFFER_LENGTH		1024
      #define MAX_EPOLL_EVENTS	1024
      #define RESOURCE_LENGTH     1024
      #define SERVER_PORT			8888
      #define PORT_COUNT			1
      
      
      #define HTTP_METHOD_GET  0 
      #define HTTP_METHOD_POST 1
      typedef int NCALLBACK(int ,int, void*);
      
      struct ntyevent {
      	int fd;
      	int events;
      	void *arg;
      	int (*callback)(int fd, int events, void *arg);
      	
      	int status;
      	char buffer[BUFFER_LENGTH];
      	char wbuffer[BUFFER_LENGTH];
      	int length;
      	int wlength;
      	//long last_active;
      
      	//about http
      	int method;
      	char resource[RESOURCE_LENGTH];
      
      };
      

      開始處理我們的GET請求的代碼

      int my_http_request(struct ntyevent * ev){
      	char lineBuffer[BUFFER_LENGTH]={0};
      	if (strstr(lineBuffer,"GET"))
      	{
      		ev->method=HTTP_METHOD_GET;
      
      		int i=0;
      		while (lineBuffer[sizeof("GET "+i)]!=' ')
      		{
      			/* code */
      			i++;
      		}
      		lineBuffer[sizeof("GET ") + i] = '\0';
      
      		sprintf(ev->resource, "%s/%s", HTTP_WEB_ROOT, lineBuffer+sizeof("GET "));
      		printf("resource: %s\n", ev->resource);		 
      	}
      	
      
      }
      

      然后,我們在接受到HTTP請求的時候,就是組裝我們的一下她HTTP請求的資源。

      int my_http_response_get_method(struct ntyevent* ev){
      	printf("call my_http_response_get_method\n");
      	//如果是網頁的話
      		int len;
      	int filefd = open(ev->resource, O_RDONLY);
      	if (filefd == -1) {
      
      		len = sprintf(ev->wbuffer, 
      		"HTTP/1.1 200 OK\r\n"
      	"Accept-Ranges: bytes\r\n"
      	"Content-Length: 78\r\n"
      	"Content-Type: text/html\r\n"
      	"Date: Sat, 06 Aug 2022 13:16:46 GMT\r\n\r\n"
      	"<html><head><title>0voice.king</title></head><body><h1>King</h1><body/></html>");
      
      		ev->wlength = len;
      	
      	} else {
      
      		struct stat stat_buf;
      		fstat(filefd, &stat_buf);
      		close(filefd);
      		len = sprintf(ev->wbuffer, 
      		"HTTP/1.1 200 OK\r\n"
      		"Accept-Ranges: bytes\r\n"
      		"Content-Length: %ld\r\n"
      		"Content-Type: text/html\r\n"
      		"Date: Sat, 06 Aug 2022 13:16:46 GMT\r\n\r\n", stat_buf.st_size);
      
      		ev->wlength = len;
      	}
      	return len;
      
      }
      
      int my_http_response(struct ntyevent * ev){
      	if (ev->method == HTTP_METHOD_GET) {
      		return my_http_response_get_method(ev);
      	} else if (ev->method == HTTP_METHOD_POST) {
      
      	}
      }
      

      最后我們的代碼如下:

      
      
      
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <sys/socket.h>
      #include <sys/epoll.h>
      #include <arpa/inet.h>
      
      #include <sys/types.h>
      #include <sys/stat.h>
      
      
      #include <fcntl.h>
      #include <unistd.h>
      #include <errno.h>
      #include <sys/time.h>
      
      #include <sys/sendfile.h>
      
      
      #define BUFFER_LENGTH		1024
      #define MAX_EPOLL_EVENTS	1024
      #define RESOURCE_LENGTH     1024
      #define SERVER_PORT			8888
      #define PORT_COUNT			1
      
      
      #define HTTP_METHOD_GET  0 
      #define HTTP_METHOD_POST 1
      
      #define HTTP_WEB_ROOT	"/home/lwl/share/http/root"
      
      typedef int NCALLBACK(int ,int, void*);
      
      struct ntyevent {
      	int fd;
      	int events;
      	void *arg;
      	int (*callback)(int fd, int events, void *arg);
      	
      	int status;
      	char buffer[BUFFER_LENGTH];
      	char wbuffer[BUFFER_LENGTH];
      	int length;
      	int wlength;
      	//long last_active;
      
      	//about http
      	int method;
      	char resource[RESOURCE_LENGTH];
      
      };
      
      struct eventblock {
      	
      	struct eventblock *next;
      	struct ntyevent *events;
      };
      
      struct ntyreactor {
      	int epfd;
      	int blkcnt;
      
      	struct eventblock *evblks;
      };
      
      
      int recv_cb(int fd, int events, void *arg);
      int send_cb(int fd, int events, void *arg);
      struct ntyevent *ntyreactor_idx(struct ntyreactor *reactor, int sockfd);
      
      
      
      void nty_event_set(struct ntyevent *ev, int fd, NCALLBACK callback, void *arg) {
      
      	ev->fd = fd;
      	ev->callback = callback;
      	ev->events = 0;
      	ev->arg = arg;
      	//ev->last_active = time(NULL);
      
      	return ;
      	
      }
      
      
      int nty_event_add(int epfd, int events, struct ntyevent *ev) {
      
      	struct epoll_event ep_ev = {0, {0}};
      	ep_ev.data.ptr = ev;
      	ep_ev.events = ev->events = events;
      
      	int op;
      	if (ev->status == 1) {
      		op = EPOLL_CTL_MOD;
      	} else {
      		op = EPOLL_CTL_ADD;
      		ev->status = 1;
      	}
      
      	if (epoll_ctl(epfd, op, ev->fd, &ep_ev) < 0) {
      		printf("event add failed [fd=%d], events[%d]\n", ev->fd, events);
      		return -1;
      	}
      
      	return 0;
      }
      
      int nty_event_del(int epfd, struct ntyevent *ev) {
      
      	struct epoll_event ep_ev = {0, {0}};
      
      	if (ev->status != 1) {
      		return -1;
      	}
      
      	ep_ev.data.ptr = ev;
      	ev->status = 0;
      	epoll_ctl(epfd, EPOLL_CTL_DEL, ev->fd, &ep_ev);
      
      	return 0;
      }
      int readline(char* allbuf,int idx,char * linebuf){
      	int len=strlen(allbuf);
      
      	for (;idx < len; idx++)
      	{
      		/* code */
      		if (allbuf[idx]=='\r'||allbuf[idx+1]=='\n')
      		{
      			return idx+2;
      		}else{
      			*(linebuf++)=allbuf[idx];
      		}
      		
      	}
      	
      }
      int my_http_request(struct ntyevent * ev){
      	char lineBuffer[BUFFER_LENGTH]={0};
      	printf("CALL in my_http_request\n");
      	int idx = readline(ev->buffer, 0, lineBuffer);
      	printf("lineBuffer:%s \n",lineBuffer);
      	if (strstr(lineBuffer,"GET"))
      	{
      		printf("CALL in get case my_http_request\n");
      		ev->method=HTTP_METHOD_GET;
      
      		int i = 0;
      		while(lineBuffer[sizeof("GET ") + i] != ' ') i ++;
      		lineBuffer[sizeof("GET ") + i] = '\0';
      
      		sprintf(ev->resource, "%s/%s", HTTP_WEB_ROOT, lineBuffer+sizeof("GET "));
      		printf("resource: %s\n", ev->resource);		 
      	}
      	
      
      }
      int recv_cb(int fd, int events, void *arg) {
      
      	struct ntyreactor *reactor = (struct ntyreactor*)arg;
      	struct ntyevent *ev = ntyreactor_idx(reactor, fd);
      
      	if (ev == NULL) return -1;
      
      	int len = recv(fd, ev->buffer, BUFFER_LENGTH, 0);
      	nty_event_del(reactor->epfd, ev);
      
      	if (len > 0) {
      		
      		ev->length = len;
      		ev->buffer[len] = '\0';
      
      		my_http_request(ev);
      		nty_event_set(ev, fd, send_cb, reactor);
      		nty_event_add(reactor->epfd, EPOLLOUT, ev);
      		
      		
      	} else if (len == 0) {
      
      		nty_event_del(reactor->epfd, ev);
      		printf("recv_cb --> disconnect\n");
      		close(ev->fd);
      		 
      	} else {
      
      		if (errno == EAGAIN && errno == EWOULDBLOCK) { //
      			
      		} else if (errno == ECONNRESET){
      			nty_event_del(reactor->epfd, ev);
      			close(ev->fd);
      		}
      		printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));
      		
      	}
      
      	return len;
      }
      int my_http_response_get_method(struct ntyevent* ev){
      	printf("call my_http_response_get_method\n");
      	//如果是網頁的話
      		int len;
      	int filefd = open(ev->resource, O_RDONLY);
      	if (filefd == -1) {
      
      		len = sprintf(ev->wbuffer, 
      		"HTTP/1.1 200 OK\r\n"
      	"Accept-Ranges: bytes\r\n"
      	"Content-Length: 78\r\n"
      	"Content-Type: text/html\r\n"
      	"Date: Sat, 06 Aug 2022 13:16:46 GMT\r\n\r\n"
      	"<html><head><title>0voice.king</title></head><body><h1>King</h1><body/></html>");
      
      		ev->wlength = len;
      	
      	} else {
      
      		struct stat stat_buf;
      		fstat(filefd, &stat_buf);
      		close(filefd);
      		len = sprintf(ev->wbuffer, 
      		"HTTP/1.1 200 OK\r\n"
      		"Accept-Ranges: bytes\r\n"
      		"Content-Length: %ld\r\n"
      		"Content-Type: text/html\r\n"
      		"Date: Sat, 06 Aug 2022 13:16:46 GMT\r\n\r\n", stat_buf.st_size);
      
      		ev->wlength = len;
      	}
      	return len;
      
      }
      
      int my_http_response(struct ntyevent * ev){
      	if (ev->method == HTTP_METHOD_GET) {
      		return my_http_response_get_method(ev);
      	} else if (ev->method == HTTP_METHOD_POST) {
      
      	}
      }
      int send_cb(int fd, int events, void *arg) {
      
      	struct ntyreactor *reactor = (struct ntyreactor*)arg;
      	struct ntyevent *ev = ntyreactor_idx(reactor, fd);
      
      	if (ev == NULL) return -1;
      	
      	my_http_response(ev);
      	int len = send(fd, ev->wbuffer, ev->wlength, 0);
      	if (len > 0) {
      		printf("send[fd=%d], [%d]%s\n", fd, len, ev->wbuffer);
      
      		int filefd = open(ev->resource, O_RDONLY);
      		struct stat stat_buf;
      		fstat(filefd, &stat_buf);
      		
      		int flag = fcntl(fd, F_GETFL, 0);
      		flag &= ~O_NONBLOCK;
      		fcntl(fd, F_SETFL, flag);
      			
      		int ret = sendfile(fd, filefd, NULL, stat_buf.st_size);
      		if (ret == -1) {
      			printf("sendfile: errno: %d\n", errno);
      		}
      
      		flag |= O_NONBLOCK;
      		fcntl(fd, F_SETFL, flag);
      
      		close(filefd);
      
      		send(fd, "\r\n", 2, 0);
      
      		nty_event_del(reactor->epfd, ev);
      		nty_event_set(ev, fd, recv_cb, reactor);
      		nty_event_add(reactor->epfd, EPOLLIN, ev);
      		
      	} else {
      
      		nty_event_del(reactor->epfd, ev);
      		close(ev->fd);
      
      		printf("send[fd=%d] error %s\n", fd, strerror(errno));
      
      	}
      
      	return len;
      }
      
      int accept_cb(int fd, int events, void *arg) {
      
      	struct ntyreactor *reactor = (struct ntyreactor*)arg;
      	if (reactor == NULL) return -1;
      
      	struct sockaddr_in client_addr;
      	socklen_t len = sizeof(client_addr);
      
      	int clientfd;
      
      	if ((clientfd = accept(fd, (struct sockaddr*)&client_addr, &len)) == -1) {
      		if (errno != EAGAIN && errno != EINTR) {
      			
      		}
      		printf("accept: %s\n", strerror(errno));
      		return -1;
      	}
      
      	
      	int flag = 0;
      	if ((flag = fcntl(clientfd, F_SETFL, O_NONBLOCK)) < 0) {
      		printf("%s: fcntl nonblocking failed, %d\n", __func__, MAX_EPOLL_EVENTS);
      		return -1;
      	}
      
      	struct ntyevent *event = ntyreactor_idx(reactor, clientfd);
      
      	if (event == NULL) return -1;
      		
      	nty_event_set(event, clientfd, recv_cb, reactor);
      	nty_event_add(reactor->epfd, EPOLLIN, event);
      
      	
      
      	printf("new connect [%s:%d], pos[%d]\n", 
      		inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), clientfd);
      
      	return 0;
      
      }
      
      int init_sock(short port) {
      
      	int fd = socket(AF_INET, SOCK_STREAM, 0);
      	fcntl(fd, F_SETFL, O_NONBLOCK);
      
      	struct sockaddr_in server_addr;
      	memset(&server_addr, 0, sizeof(server_addr));
      	server_addr.sin_family = AF_INET;
      	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      	server_addr.sin_port = htons(port);
      
      	bind(fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
      
      	if (listen(fd, 20) < 0) {
      		printf("listen failed : %s\n", strerror(errno));
      		return -1;
      	}
      
      	printf("listen server port : %d\n", port);
      	return fd;
      }
      
      
      int ntyreactor_alloc(struct ntyreactor *reactor) {
      
      	if (reactor == NULL) return -1;
      	if (reactor->evblks == NULL) return -1;
      	
      	struct eventblock *blk = reactor->evblks;
      
      	while (blk->next != NULL) {
      		blk = blk->next;
      	}
      
      	struct ntyevent* evs = (struct ntyevent*)malloc((MAX_EPOLL_EVENTS) * sizeof(struct ntyevent));
      	if (evs == NULL) {
      		printf("ntyreactor_alloc ntyevent failed\n");
      		return -2;
      	}
      	memset(evs, 0, (MAX_EPOLL_EVENTS) * sizeof(struct ntyevent));
      
      	struct eventblock *block = malloc(sizeof(struct eventblock));
      	if (block == NULL) {
      		printf("ntyreactor_alloc eventblock failed\n");
      		return -3;
      	}
      	block->events = evs;
      	block->next = NULL;
      
      	blk->next = block;
      	reactor->blkcnt ++;
      
      	return 0;
      }
      
      struct ntyevent *ntyreactor_idx(struct ntyreactor *reactor, int sockfd) {
      
      	if (reactor == NULL) return NULL;
      	if (reactor->evblks == NULL) return NULL;
      
      	int blkidx = sockfd / MAX_EPOLL_EVENTS;
      	while (blkidx >= reactor->blkcnt) {
      		ntyreactor_alloc(reactor);
      	}
      
      	int i = 0;
      	struct eventblock *blk = reactor->evblks;
      	while (i++ != blkidx && blk != NULL) {
      		blk = blk->next;
      	}
      
      	return &blk->events[sockfd % MAX_EPOLL_EVENTS];
      }
      
      
      int ntyreactor_init(struct ntyreactor *reactor) {
      
      	if (reactor == NULL) return -1;
      	memset(reactor, 0, sizeof(struct ntyreactor));
      
      	reactor->epfd = epoll_create(1);
      	if (reactor->epfd <= 0) {
      		printf("create epfd in %s err %s\n", __func__, strerror(errno));
      		return -2;
      	}
      
      	struct ntyevent* evs = (struct ntyevent*)malloc((MAX_EPOLL_EVENTS) * sizeof(struct ntyevent));
      	if (evs == NULL) {
      		printf("create epfd in %s err %s\n", __func__, strerror(errno));
      		close(reactor->epfd);
      		return -3;
      	}
      	memset(evs, 0, (MAX_EPOLL_EVENTS) * sizeof(struct ntyevent));
      
      	struct eventblock *block = malloc(sizeof(struct eventblock));
      	if (block == NULL) {
      		free(evs);
      		close(reactor->epfd);
      		return -3;
      	}
      	block->events = evs;
      	block->next = NULL;
      
      	reactor->evblks = block;
      	reactor->blkcnt = 1;
      
      	return 0;
      }
      
      int ntyreactor_destory(struct ntyreactor *reactor) {
      
      	close(reactor->epfd);
      
      	struct eventblock *blk = reactor->evblks;
      	struct eventblock *blk_next;
      	while (blk != NULL) {
      		blk_next = blk->next;
      
      		free(blk->events);
      		free(blk);
      		
      		blk = blk_next;
      	}
      
      	return 0;
      }
      
      
      
      int ntyreactor_addlistener(struct ntyreactor *reactor, int sockfd, NCALLBACK *acceptor) {
      
      	if (reactor == NULL) return -1;
      	if (reactor->evblks == NULL) return -1;
      
      	struct ntyevent *event = ntyreactor_idx(reactor, sockfd);
      	if (event == NULL) return -1;
      
      	nty_event_set(event, sockfd, acceptor, reactor);
      	nty_event_add(reactor->epfd, EPOLLIN, event);
      
      	return 0;
      }
      
      
      
      int ntyreactor_run(struct ntyreactor *reactor) {
      	if (reactor == NULL) return -1;
      	if (reactor->epfd < 0) return -1;
      	if (reactor->evblks == NULL) return -1;
      	
      	struct epoll_event events[MAX_EPOLL_EVENTS+1];
      	
      	int checkpos = 0, i;
      
      	while (1) {
      
      		int nready = epoll_wait(reactor->epfd, events, MAX_EPOLL_EVENTS, 1000);
      		if (nready < 0) {
      			printf("epoll_wait error, exit\n");
      			continue;
      		}
      
      		for (i = 0;i < nready;i ++) {
      
      			struct ntyevent *ev = (struct ntyevent*)events[i].data.ptr;
      
      			if ((events[i].events & EPOLLIN) && (ev->events & EPOLLIN)) {
      				ev->callback(ev->fd, events[i].events, ev->arg);
      			}
      			if ((events[i].events & EPOLLOUT) && (ev->events & EPOLLOUT)) {
      				ev->callback(ev->fd, events[i].events, ev->arg);
      			}
      			
      		}
      
      	}
      }
      
      int main(int argc, char *argv[]) {
      
      	
      	struct ntyreactor *reactor = (struct ntyreactor*)malloc(sizeof(struct ntyreactor));
      	ntyreactor_init(reactor);
      
      	unsigned short port = SERVER_PORT;
      	if (argc == 2) {
      		port = atoi(argv[1]);
      	}
      
      	int i = 0;
      	int sockfds[PORT_COUNT] = {0};
      	
      	for (i = 0;i < PORT_COUNT;i ++) {
      		sockfds[i] = init_sock(port+i);
      		ntyreactor_addlistener(reactor, sockfds[i], accept_cb);
      	}
      
      
      	ntyreactor_run(reactor);
      
      	ntyreactor_destory(reactor);
      	
      	for (i = 0;i < PORT_COUNT;i ++) {
      		close(sockfds[i]);
      	}
      	free(reactor);
      	
      
      	return 0;
      }
      
      

      最后看一看,我們實現的結果是什么樣子的?

      推薦一個零聲學院免費教程,個人覺得老師講得不錯,
      分享給大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
      fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,
      TCP/IP,協程,DPDK等技術內容,點擊立即學習:
      服務器
      音視頻
      dpdk
      Linux內核

      posted @ 2022-10-24 00:00  飄雨的河  閱讀(287)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 美欧日韩一区二区三区视频| 一区二区三区不卡国产| 欧洲精品色在线观看| 东京热人妻无码人av| 一本色道久久东京热| 国产免费无遮挡吸奶头视频| 国产精品人成视频免费播放| 国产日韩乱码精品一区二区 | 日韩精品中文字幕第二页| 国产麻豆精品久久一二三| 亚洲精品无码久久一线| 国产无遮挡猛进猛出免费软件| 亚州中文字幕一区二区| 亚洲 自拍 另类小说综合图区| 色欲久久综合亚洲精品蜜桃| 亚洲人妻一区二区精品| 99蜜桃在线观看免费视频网站| 国产高清在线精品一区二区三区 | 国产美女遭强高潮免费| 69天堂人成无码免费视频| 先锋影音av最新资源| 亚洲国产欧美在线人成aaaa| 美女裸体黄网站18禁止免费下载 | 日韩精品国产二区三区| 乱人伦人妻系列| 亚洲AV午夜电影在线观看| 日韩av日韩av在线| 性欧美暴力猛交69hd| 亚洲人成网站免费播放| 国产精品三级中文字幕| 他掀开裙子把舌头伸进去添视频| 99精品视频在线观看婷婷| 四虎精品视频永久免费| 国产精品午夜无码AV天美传媒 | 亚洲精品国产一区二区在线观看| 老师扒下内裤让我爽了一夜| 日本免费人成视频在线观看| 国产日韩另类综合11页| 亚洲 日本 欧洲 欧美 视频| 韩国午夜福利片在线观看| 饥渴的熟妇张开腿呻吟视频|