实现高并发服务器三种简化模型 线程 进程 IO复用
2016-05-24 18:30
537 查看
知识点:UNIX网络编程第四章, 第五章,第六章
多进程模型:
多线程模型:编译时记得加上 -lpthread
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<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); }
相关文章推荐
- 小心服务器内存居高不下的元凶--WebAPI服务
- Unix 即将迎来 50 岁
- 运维入门
- Linux VS Unix:Linux欲一统天下 Unix不死
- 利用开源软件打造自己的全功能远程工具
- Linux5.9无人值守安装
- 数据中心和云未来的十二大趋势
- 用vsftp快速搭建ftp服务器
- Linux快速构建apache web服务器
- 服务器监控策略浅谈
- 如何降低服务器采购成本 原理分析
- 建议的服务器分区办法
- 服务器托管六大优势分析
- Erlang实现的一个Web服务器代码实例
- 服务器技术全面解析
- 保护DNS服务器的几点方法小结
- 我国成为全球第二大服务器消费国
- 服务器 安全检查要点[星外提供]
- 服务器应用自动重新启动IIS批处理[原创]_DOS/BAT_脚本之家