高性能网络编程 - 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(面向对象)层层封装过的开源组件),相比于服务器的运行效率而言,他们更关注程序开发 的效率,追求更快的完成项目功能点.希望应用代码完全 ...
随机推荐
- ActiveMQ学习笔记(16)----Message Dispatch高级特性(二)
1. Optimized Acknowledgetment ActiveMQ缺省支持批量确认消息,由于批量确认会提高性能,如果希望在应用程序中禁止经过优化的确认方式,可以采用以下几种方式: 1. 在C ...
- 为什么maven 创建web工程不自动生成Deployment Descriptor:工程名
上面图切换成下面图: 点击eclipse右上角,如下图红圈,然后在选择javaEE这样就切换成javaEE视图了 如果还是不能解决,相信这个链接对你有所帮助:https://www.cnblogs.c ...
- 贰、js的基础(二)类型转换
JS 数据类型转换 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把 ...
- 基本数据类型(list、tuple)
1.列表 1.1 定义 li=[1,2,3] 每个元素逗号隔开 list("abc") 迭代 列表是一个容器 => 任意类型 列表是有序的 => 索引 切片 步长 列表 ...
- NodeJS学习笔记 (7)网络服务-http-client(ok)
原文:https://github.com/chyingp/nodejs-learning-guide 自己敲代码: ClientRequest概览 当你调用 http.request(options ...
- iOS开发——GCD总结
Grand Central Dispatch,简称GCD,在异步执行任务的技术之一. 一般将应用程序中记述的线程管理用的代码在系统级中实现,开发者只需要定义想执行的任务并追加到适当的Dispatch ...
- [HAOI2016]找相同字符(SAM+DP)
感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...
- RPC架构
RPC架构 学习了: https://www.cnblogs.com/ChrisMurphy/p/6550184.html RPC架构简介,有一个Java例子: http://blog.csdn.ne ...
- HDU 2222 Keywords Search(AC自己主动机模板题)
题意:给出一个字符串和若干个模板,求出在文本串中出现的模板个数. 思路:由于有可能有反复的模板,trie树权值记录每一个模板出现的次数就可以. #include<cstdio> #incl ...
- 每一个人都懂得敏捷开发 (软件project), 为何产品开发的效率与质量还是这么的烂?
敏捷开发(软件project)是 "设计" 出来的.不是 "学" 来的-- 很多人都一直在质疑敏捷开发能否提高效率与质量? 更有不少人以嘲讽.不屑的口吻看待软件 ...