Linux 网络编程九(select应用--大并发处理)
//网络编程服务端
/*
* 备注:因为客户端代码、辅助方法代码和epoll相同,所以select只展示服务器端代码
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>//htons()函数头文件
#include <netinet/in.h>//inet_addr()头文件
#include <fcntl.h>
#include <sys/select.h>
#include <time.h>
#include "pub.h" #define MAXSOCKET 1024 int main(int arg, char *args[])
{
if (arg < )
{
printf("please print one param!\n");
return -;
}
//create server socket
int listen_st = server_socket(atoi(args[]));
if (listen_st < )
{
return -;
}
//设置非阻塞文件描述符
setnonblock(listen_st);
int i = ;
int maxfd = ; //最大的socket,select函数第一个参数使用
/*
*建立客户端连接池
*/
int client[MAXSOCKET]; //select最大支持1024个socket连接
//将所有的客户端连接池初始化,将每个成员都设置为-1,表示无效
for (; i < MAXSOCKET; i++)
{
client[i] = -;
}
maxfd = listen_st; //程序刚开始执行时,只有服务端socket,所以服务端socket最大
//定义一个事件数组结构
fd_set allset;
while ()
{
//初始化一个fd_set对象
FD_ZERO(&allset);
//将服务器端socket放入事件数组allset中(服务端socket需要特殊处理,所以没有放入socket池中)
FD_SET(listen_st, &allset);
//先假设最大的socket就是服务器端socket
maxfd = listen_st;
//遍历socket池 找出值最大的socket
for (i = ; i < MAXSOCKET; i++)
{
if (client[i] != -)
{
//将socket池中的所有socket都添加到事件数组allset中
FD_SET(client[i], &allset);
if (client[i] > maxfd)
{
maxfd = client[i]; //maxfd永远是值最大的socket
}
}
}
//开始等待socket发生读事件
int rc = select(maxfd + , &allset, NULL, NULL, NULL);
/*
* select函数返回之后,allset数组的数据产生变化,现在allset数组里的数据是发生事件的socket
* select和epoll不同,select每次返回后,
* 会清空select池中的所有socket,所有的socket等select返回后就被清除了
* 所以必须由程序建立一个socket池,每次都将socket池中的socket加入到select池中
* select不会为程序保存socket信息,这与epoll最大的不同,
* epoll添加到events中的socket,如果不是程序员清除,epoll永远保留这些socket
*/
if (rc < )
{
//select函数出错,跳出循环
printf("select failed ! error message:%s\n", strerror(errno));
break;
}
//判断是否是服务器socket接收到数据,有客户端连接
if (FD_ISSET(listen_st, &allset))
{
//accept
int client_st = server_accept(listen_st);
if (client_st < )
{
//直接跳出select循环
break;
}
//客户端连接成功 设置客户端非阻塞
setnonblock(client_st);
//将客户端socket加入socket池中
for (i = ; i < MAXSOCKET; i++)
{
if (client[i] == -)
{
client[i] = client_st;
break;
}
}
if (i == MAXSOCKET)
{
//socket池已满,关闭客户端连接
close_socket(client_st);
}
}
//处理客户端的socket
for (i = ; i < MAXSOCKET; i++)
{
if (client[i] == -)
{
//无效socket直接退出
continue;
}
//判断是否是这个socket有事件发生
if (FD_ISSET(client[i], &allset))
{
//接收消息
if (socket_recv(client[i]) < )
{
//如果接收消息出错,关闭客户端socket
close_socket(client[i]);
//从socket池中将这个socket清除
client[i] = -;
}
rc--;
}
//说明所有消息的socket已经处理完成
if (rc < )
{
//备注:双循环break只能跳出最近的一重循环
break;
}
}
}
//close server socket
close_socket(listen_st);
return ;
}
Linux 网络编程九(select应用--大并发处理)的更多相关文章
- linux网络编程九:splice函数,高效的零拷贝
from:http://blog.csdn.net/jasonliuvip/article/details/22600569 linux网络编程九:splice函数,高效的零拷贝 最近在看<Li ...
- linux网络编程:select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)
从别人的博客中转载过来了这一篇文章,经过重新编辑排版之后展现于此,做一个知识点保存与学习. select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- Linux网络编程入门 (转载)
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- [转] - Linux网络编程 -- 网络知识介绍
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- 【转】Linux网络编程入门
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- 《转》Linux网络编程入门
原地址:http://www.cnblogs.com/duzouzhe/archive/2009/06/19/1506699.html (一)Linux网络编程--网络知识介绍 Linux网络编程-- ...
- Linux网络编程入门
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"
[深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...
随机推荐
- SQL Server 2008 R2——学习/练习/错误/总结/搜集
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...
- Centos 下oracle 11g 安装部署及手动建库过程
Oracle 11g 手动建库,在虚拟环境中,不使用DBCA工具进行创建数据库 1.Linux环境的基本配置 2.ip 10.11.30.60 3.Oracle 11g安装过程 ---------- ...
- JDK自带工具一览表。妈妈再也不用担心你到处去下载小软件了~~
原来JDK早早就给我准备好了要用到的工具..反编译,JVM性能监视.诊断. JDK(Java Development Kit)是Java程序员最核心的开发工具,没有之一. JDK是一个功能强大的Jav ...
- Dreamweaver 制作图片热点之后,点击热点部分会有个提示框,怎么去掉
可以这么写试试看<map name="Map"> <area shape="rect" coords="364,31,517,64& ...
- 原始的2文件的makefile错误
从来没系统的看过makefile文档,平时属于复制模板,用完即忘,下午尝试按自己的理解写一个最简单的makefile,含2个.c文件,1个.h文件,费了个把小时,参考别人的文章才弄出来,特记录. ma ...
- FileOutputFormat
TextOutputFormat<K,V> 默认输出字符串输出格式: SequenceFileOutputFormat<K,V> 序列化文件输出: MultipleOutput ...
- 初探Team Foundation Server (TFS) 2015 REST API
REST是一种简洁方便的Web服务,通过基于http协议的远程通信,可以为多种客户端程序提供远程服务,大幅提高了服务器系统的可扩展性. 微软宣布从Team Foundation Server 从201 ...
- uva 1471 defence lines——yhx
After the last war devastated your country, you - as the king of the land of Ardenia - decided it wa ...
- uva133-S.B.S.
The Dole Queue In a serious attempt to downsize (reduce) the dole queue, The New National Green Lab ...
- 【OpenCV】全景拼接
从OpenCV3.0正式版开始,features2d中的一些接口,搬到附加库xfeatures2d中了,其中就有SIFT.SURF的特征检测方法,但是正常下载安装OpenCV并不包含附加库,因为附加库 ...