//网络编程服务端
/*
* 备注:因为客户端代码、辅助方法代码和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应用--大并发处理)的更多相关文章

  1. linux网络编程九:splice函数,高效的零拷贝

    from:http://blog.csdn.net/jasonliuvip/article/details/22600569 linux网络编程九:splice函数,高效的零拷贝 最近在看<Li ...

  2. linux网络编程:select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)

    从别人的博客中转载过来了这一篇文章,经过重新编辑排版之后展现于此,做一个知识点保存与学习. select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复 ...

  3. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  4. Linux网络编程入门 (转载)

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  5. [转] - Linux网络编程 -- 网络知识介绍

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  6. 【转】Linux网络编程入门

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  7. 《转》Linux网络编程入门

    原地址:http://www.cnblogs.com/duzouzhe/archive/2009/06/19/1506699.html (一)Linux网络编程--网络知识介绍 Linux网络编程-- ...

  8. Linux网络编程入门

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  9. 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"

    [深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...

随机推荐

  1. IP 协议首部格式与其配套使用的四个协议(ARP,RARP,ICMP,IGMP)

    目录 IP协议首部格式地址解析协议 ARP逆向地址解析协议 RARP网际控制报文协议 ICMP网际组管理协议IGMP IP 数据报首部 IP数据报首部格式: 最高位在左边,记为0 bit:最低位在右边 ...

  2. linux终端python自动提示

    linux终端python自动提示 很多时候,在linux下编写python时, 都懒得去vi一个新文件,直接就新开一个终端, 进入python命令行模式,然后就可以写一些测试代码. 不过最悲剧的就是 ...

  3. iOS 杂笔-20(UIView和CALayer的区别与联系)

    iOS 杂笔-20(UIView和CALayer的区别与联系) 每个 UIView 内部都有一个 CALayer 在背后提供内容的绘制和显示,并且 UIView 的尺寸样式都由内部的 Layer 所提 ...

  4. iOS网络-02-数据解析(JSON与XML)

    数据交互格式 服务器返回给用户的数据,通常是以下两种方式: JSON XML JSON 一种轻量级的数据数据格式,体积比XML小,是服务器返回给移动端通常采用的格式 用使用JSON文件中的数据,需要对 ...

  5. 关于ajax请求数据后,数据本身的js失效的一些想法

    今天遇到一个头疼的问题.我做一个左右翻页效果(客户要求能够无限翻页),所以只能动态请求数据,进行局部刷新操作. 这时候问题就出来了,当我请求翻页的时候,数据通过js填充到div里面,但这些数据,自身带 ...

  6. 响应式Web设计 – 布局

    写在前面 去年上半年,我开始着手推动项目中响应式设计的落地.以官网优化需求为契机,主动去做了响应式的页面设计,也说服了产品.设计和开发的相关同事一起把它上线落实,但不幸的是,由于各种方面的原因,比如, ...

  7. windows分离系统文件和用户数据

    2013/12/17更新:使用了一段时间,开机时有时会出现一些错误,不过不影响正常使用,不能忍的是会经常更新,所以暂时不推荐使用. 为了方便地重装系统,同时保留用户数据,想到了分离windows系统文 ...

  8. Linux Shell 04 数字/字符串/文件测试

    一. 数字测试 格式:n1  -op  n2 测试操作op: eq/ne/le/ge/lt/gt    -->    等于/不等于/小于等于/大于等于/小于/大于 1. 数字比较可以使用特殊的( ...

  9. Neo4j图数据库管理系统开发笔记之三:构建安全的RMI Service(Server)

    RMI Server(服务端)主要包括以下功能:远程用户权限验证管理.远程服务接口实现类.Neo4j实体映射转换等.项目目录结构如下图所示: 3.2.1 远程用户权限验证管理 3.2.1.1 用户权限 ...

  10. hdu 2199 Can you solve this equation?(二分搜索)

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...