實現高併發伺服器三種簡化模型 執行緒 程序 IO複用
阿新 • • 發佈:2019-02-10
知識點:UNIX網路程式設計第四章, 第五章,第六章
多程序模型:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/socket.h> #include<errno.h> #include<netinet/in.h> #define SERV_PORT 3000 #define MAXLINE 1024 void str_echo(int sockfd) { ssize_t n; char buf[MAXLINE]; again: while( (n= read(sockfd, buf ,MAXLINE)) > 0) write(sockfd, buf, n); if(n<0 && errno == EINTR) goto again; else if(n<0) printf("stro_echo:read error\n"); } void main(void) { int lfd, cfd; struct sockaddr_in serv_addr, clin_addr; socklen_t clin_len; char buf[MAXLINE]; pid_t childpid; lfd = socket(AF_INET, SOCK_STREAM, 0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); bind(lfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(lfd, 128); for(;;){ clin_len = sizeof(clin_addr); cfd = accept(lfd,(struct sockaddr*) &clin_addr, &clin_len); if( (childpid = fork()) == 0){ close(lfd); str_echo(cfd); exit(0); } close(cfd); } }
多執行緒模型:編譯時記得加上 -lpthread
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/socket.h> #include<errno.h> #include<netinet/in.h> #include<pthread.h> #define SERV_PORT 3000 #define MAXLINE 1024 static void *str_echo(void *sockfd) { ssize_t n; char buf[MAXLINE]; again: while( (n= read((int)(sockfd), buf ,MAXLINE)) > 0) write((int)(sockfd), buf, n); if(n<0 && errno == EINTR) goto again; else if(n<0) printf("stro_echo:read error\n"); close((int)sockfd); } void main(void) { int lfd, cfd; struct sockaddr_in serv_addr, clin_addr; socklen_t clin_len; char buf[MAXLINE]; pid_t childpid; lfd = socket(AF_INET, SOCK_STREAM, 0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); bind(lfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(lfd, 128); for(;;){ clin_len = sizeof(clin_addr); cfd = accept(lfd,(struct sockaddr*) &clin_addr, &clin_len); pthread_t tid; pthread_create(&tid, NULL, &str_echo,(void *) cfd); } close(lfd); }
IO複用:
因為select和poll都存在很多缺陷,這裡選用新的epoll函式來實現。
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/epoll.h> #include<errno.h> #include<netinet/in.h> #define SERV_PORT 3000 #define MAXLINE 1024 void str_echo(int sockfd) { ssize_t n; char buf[MAXLINE]; again: while( (n= read(sockfd, buf ,MAXLINE)) > 0) write(sockfd, buf, n); if(n<0 && errno == EINTR) goto again; else if(n<0) printf("stro_echo:read error\n"); } void main(void) { int lfd, cfd, efd; struct sockaddr_in serv_addr, clin_addr; socklen_t clin_len; char buf[MAXLINE]; int len, n; struct epoll_event tep, ep[1024]; lfd = socket(AF_INET, SOCK_STREAM, 0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); bind(lfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); listen(lfd, 128); efd = epoll_create(1024); tep.events = EPOLLIN; tep.data.fd = lfd; epoll_ctl(efd, EPOLL_CTL_ADD, lfd, &tep); for(;;){ n = epoll_wait(efd, ep, 1024, -1); int i = 0; for( i =0;i<n;i++){ clin_len = sizeof(clin_addr); cfd = accept(lfd,(struct sockaddr*) &clin_addr, &clin_len); str_echo(cfd); close(cfd); } } close(lfd); }