高性能网络编程 - select系统调用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h> //basename
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <assert.h>
#include <errno.h> int main(int argc, char *argv[]){
int i, maxi;
char buf[1024];
fd_set read_fds, all_read_fds;
fd_set exception_fds, all_exception_fds;
int nready, connectfd[FD_SETSIZE];
int connfd,sockfd,maxfd; struct sockaddr_in client_address;
socklen_t client_addrlen = sizeof(client_address); if(argc <= 2){
printf("usage: %s ip_address port_number\n", basename(argv[0]));
return 1;
} const char *ip = argv[1];
int port = atoi(argv[2]); int ret = 0;
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET, ip, &address.sin_addr);
address.sin_port = htons(port); int listenfd = socket(AF_INET, SOCK_STREAM, 0);
assert(listenfd >= 0);
ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
assert(ret != -1);
ret = listen(listenfd, 5);
assert(ret != -1); maxfd = listenfd;
maxi = -1;
for(i= 0; i < FD_SETSIZE; i++)
connectfd[i] = -1;
FD_ZERO(&all_read_fds);
FD_ZERO(&all_exception_fds);
FD_SET(listenfd, &all_read_fds);
//do not care about the OOB of listen socket while(1){
read_fds = all_read_fds;
exception_fds = all_exception_fds;
memset(buf, 0, sizeof(buf));
nready = select(maxfd + 1, &read_fds, NULL, &exception_fds, NULL);
//new client connection coming
if(FD_ISSET(listenfd, &read_fds)){
connfd = accept(listenfd, (struct sockaddr *)&client_address, &client_addrlen);
if(connfd < 0){
perror("accept failed\n");
exit(-1);
} for(i=0; i < FD_SETSIZE; i++)
if(connectfd[i] < 0){
connectfd[i] = connfd;
break;
}
if( i == FD_SETSIZE){
printf("too many clients..\n");
exit(-1);
}
// add new descriptor to the read set and exception set
FD_SET(connfd, &all_read_fds);
FD_SET(connfd, &all_exception_fds);
if(connfd > maxfd)
maxfd = connfd;
if(i > maxi)
maxi = i;// update the max index in connectfd[]
//we complete the listen socktet processing
if(--nready <= 0)
continue;
}
for(i = 0; i <= maxi; i++){
//check all the connected clients for data
if((sockfd = connectfd[i]) < 0)
continue;
if(FD_ISSET(sockfd, &read_fds)){
ret = recv(sockfd, buf, sizeof(buf) - 1, 0);
if(ret <= 0)
break;//connection closed
// process logic
printf("get %d bytes of normal data:%s\n", ret, buf);
//we complete the listen socktet processing
if(--nready <= 0)
continue;
}
for(i = 0; i <= maxi; i++){
//check all the connected clients for data
if((sockfd = connectfd[i]) < 0)
continue;
if(FD_ISSET(sockfd, &read_fds)){
ret = recv(sockfd, buf, sizeof(buf) - 1, 0);
if(ret <= 0)
break;//connection closed
// process logic
printf("get %d bytes of normal data:%s\n", ret, buf);
}else if(FD_ISSET(sockfd, &exception_fds)){
//handle exceptions
//get out of band data
ret = recv(connfd, buf, sizeof(buf) - 1, MSG_OOB);
if(ret <= 0)
break;
printf("get %d bytes of OOB data: %s", ret, buf); }
FD_CLR(sockfd, &all_read_fds);
FD_CLR(sockfd, &all_exception_fds);
//after we deal with this client
close(sockfd);
if(--nready <= 0)
break;
}
} close(listenfd);
return 0;
}
參考:《高性能server编程》和《UNP》
高性能网络编程 - select系统调用的更多相关文章
- 一文读懂高性能网络编程中的I/O模型
1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...
- 【原创】高性能网络编程(二):上一个10年,著名的C10K并发连接问题
1.前言 对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解."C10K"概念最早由Dan Kegel发布于其个人 ...
- 【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了
转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上 ...
- 网络编程select函数
select函数的作用: 在编程的过程中,经常会遇到许多阻塞的函数,好像read和网络编程时使用的recv, recvfrom函数都是阻塞的函数,当函数不能成功执行的时候,程序就会一直阻塞在这里,无法 ...
- 高性能网络编程(一)----accept建立连接
编写服务器时,许多程序员习惯于使用高层次的组件.中间件(例如OO(面向对象)层层封装过的开源组件),相比于服务器的运行效率而言,他们更关注程序开发的效率,追求更快的完成项目功能点.希望应用代码完全不关 ...
- Linux之select系统调用_2
在上一篇博文中,我们的程序中我们有3个客户端,因此也事先建立了3个管道,每个客户端分别使用一个管道向服务器发送消息.而在服务器端使用select系统调用,只要监测到某一管道有消息写入,服务器就将其re ...
- Linux之select系统调用_1
SYNOPSIS /* According to POSIX.1-2001 */ #include <sys/select.h> /* According to earlier stand ...
- winsock编程select模型
winsock编程select模型 网络服务端连接数量过多时,为每一个连接申请一个线程会让机器性能急剧下降(大多说是因为线程在用户态和内核态之间切换会占用大量的CPU时间片).为了解决多线程带来的性能 ...
- 高性能网络编程(1)—accept建立连接(转载,作者:陶辉)
编 写服务器时,许多程序员习惯于使用高层次的组件.中间件(例如OO(面向对象)层层封装过的开源组件),相比于服务器的运行效率而言,他们更关注程序开发 的效率,追求更快的完成项目功能点.希望应用代码完全 ...
随机推荐
- 2,HTTP请求应答返回码
200 OK 请求成功,一般用于Get和Post请求 300 多种选择.请求的资源可包括多个位置,响应的返回一个资源特征与地址的列表用于浏览器(client)选择 Multiple Choices 3 ...
- jquery复制到剪贴板
<!DOCTYPE html> <html> <head> <title>ZeroClipboard Test</title> <me ...
- Java XSSF 导出excel 工具类
参数解释: title:导出excel标题.headers 导出到excel显示的列头. columns 对应数据库字段 .list 导出数据1.pox中添加依赖 <dependency> ...
- 堆(Heap)-c实现
这个堆的实现采用数组存储的完全二叉树实现. 最近有点烦躁,先是跳槽到了一个外包公司,感觉2016有点坑,另外一件事就是老婆怀孕了,但是在家里没人照顾,很担心. 这个堆的实现就暂时不优化了,基本的插入, ...
- 紫书 例题8-10 UVa 714 (二分答案)
这道题让最大值最小, 显然是二分答案 当题目求的是最大值最小, 最小值最大, 这个时候就要想到二分答案 为什么可以二分答案呢, 因为这个时候解是单调性的, 如果简单粗暴一点 就全部枚举一遍, 验证答案 ...
- pythonweb django的学习
Django 环境搭建及创建项目 首先安装django包,我使用的是pycharm,所以直接在IDE中就可以直接安装,但是django还需要手动配置系统变量 找到python根目录下的django文件 ...
- Linux修改Linux默认打开方式
从总体上讲 /etc/gnome/defaults.list 保存了全局的打开方式 /.local/share/applications/mimeapps.list 保存了个人的打开方式当两着不一致是 ...
- HDU 1022 Train Problem I 模拟栈题解
火车进站,模拟一个栈的操作,额外的栈操作,查看能否依照规定顺序出栈. 数据量非常少,故此题目非常easyAC. 直接使用数组模拟就好. #include <stdio.h> const i ...
- [Servlet&JSP] HttpSession会话管理
我们能够将会话期间必须共享的资料保存在HttpSession中,使之成为属性.假设用户关掉浏览器接受Cookie的功能.HttpSession也能够改用URL重写的方式继续其会话管理功能. HttpS ...
- 关于DPM(Deformable Part Model)算法中模型可视化的解释
搭建了自己的博客平台,本文地址:http://masikkk.com/blog/DPM-model-visualization/ DPM源代码(voc-release)中的模型可视化做的还算相当炫酷的 ...