linux select代码框架

#define PORT  1234
#define BACKLOG 5
#define MAXDATASIZE 1000
typedef struct CLIENT{
   int fd;
   char* name;
   struct sockaddr_in addr;//addr用client_addr更加准确
   char*data;
   };
 void main(){
 int i,maxi,maxfd,sockfd;
 in nready;
 fd_set rset,allset;//allset是我们要监控的fd集合,由于每次调用select都会更改监控的fd集合状态,所以再次调用的时候,需要重新设置fd集合,这里可以用allset保持监控集合,每次调用的时候用rset。改变的只是rset
 ssize_t n;
 int listenfd.connfd;
 struct sockaddr_in server_addr, client_addr;//注意,这里我们把client端的信息保存在CLIENT结构体中,
 CLIENT client[FD_SETSIZE];//FD_SETSIZE是宏常量
 char buf[MAXDATASIZE];
 int sin_size;
 if(listenfd=socket(AF_INET,SOCK_STREAM,0)==-1){
   perror("create socket failed");
   exit(1);
   }
 bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(PORT);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(listenfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)==-1)
 {  perror("bind socket failed");
   exit(1);
   }
if(listen(listenfd,BACKLOG)==-1)
{  perror("listen socket failed");
   exit(1);
}
sin_size=sizeof(struct sockaddr_in)  

maxfd=listenfd;//最大的文件描述符
maxi=-1;  //最大的用过的CLIENT数组下标
for(i=0;i<FD_SETSIZE;i++){
   client[i].fd=-1;
 }//初始化client数组
 FD_ZERO(&allset);
 FD_SET(listenfd,&allset);//加入监听

while(1){
 struct sockaddr_in addr;  //用于返回client端的信息
 rset=allset;// 再次重新赋值
 nready=select(maxfd+1,&rset,NULL,NULL,NULL)//这测试FD读就绪,写的fdset为NULL

  if(FD_ISSET(listenfd,&allset)){   //new client connection
    if((connfd=accept(listenfd,(struct sockaddr*)&addr,&sin_size))==-1)
      {    perror("accept() error\n");
           exit(1);
           continue;
        }
  for(i=0;i<FD_SETSIZE;i++)
     if(client[i].fd<0){
         client[i].fd=connfd;
         client[i].name=new char[MAXDATASIZE];
         client[i].addr=addr;//客服端的socket地址信息
          printf(" you got a connection from client");
         break;
       }

   if(i==FD_SETSIZE)  printf("too many connection")//;连接数的FD已经超过最大的1024
   FD_SET(connfd,&allset);//把connfd加入监听集合中
   if(connfd>maxfd)  maxfd=connfd;//更新目前最大的FD;
   if(i>maxi)   maxi=i;
   if(--nready<=0) continue;//之前select返回的时候只有一个监听listen是就绪的,则继续循环while(1),下面的程序不执行
   }       //对应 if(FD_ISSET(listenfd,&allset))
   for(i=0;i<=maxfd;i++){
     if((sockfd=client[i].fd<0)) continue;
     if(FD_ISSET(sockfd,&rset)){//分两种情况,一种是此FD由于关闭连接,而变成可读
       if( (n=recv(sockfd,recvbuf,MAXDATASIZE,0))==0){
                close(sockfd);//关闭这个连接对应服务器的连接socket
                FD_CLR(sockfd,&allset);//从监控的FD集合中删除
                ..................
                 ...................
         }
       else
         process(&client[i],revbuf,n)//否则就是读就绪,进行我们的操作
       if(--nready<=0) break;//处理完了所有的就绪描述符
    }
  }
 }
 close(listenfd);//调出while
}
时间: 2024-11-07 11:05:57

linux select代码框架的相关文章

linux 通用时钟框架CCF

linux 通用时钟框架CCF 简介 这里讲的时钟是给soc各组件提供时钟的树状框架,并不是内核使用的时间,和其他模块一样,clk也有框架,用以适配不同的平台.适配层之上是客户代码和接口,也就是各模块(如需要时钟信号的外设,usb等)的驱动.适配层之下是具体的soc平台的时钟操作细节. 内核中另外一个具有类似树状框架特点的是regulator框架.对比regulator框架,clk框架不确定性更大,内核中仅仅提供了少数的适配规范,struct clk都是各平台自己的clk驱动实现.       

Linux USB驱动框架分析 【转】

转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结当然不可缺,更何况我决定为嵌入式卖命了.好,言归正传,我说一说这段时间的收获,跟大家分享一下Linux的驱动开发.但这次只先针对Linux的USB子系统作分析,因为周五研讨老板催货.当然,还会顺带提一下其他的驱动程序写法. 事实上,Linux的设备驱动都遵循一个惯例——表征驱动程序(用driver更

Tweetable Mathematical Art 代码框架

昨晚在微信公众号看到 <有没有一段代码,让你觉得人类的智慧也可以璀璨无比>里面介绍了一个叫<Tweetable Mathematical Art>的代码游戏,看完我激动不已,这些人都太NB了. 我迫不及待要试一下,可惜该游戏原来的框架生成的图片上ppm格式的,在Windwos上打开比较麻烦,所以我索性写了一个生成bmp格式的代码框架. 如果有新idea的话可以在body.hpp中加入一个新类就可以了,这个代码框架可在linux和Windows上跑. pic.hpp #ifndef 

自己动手设计并实现一个linux嵌入式UI框架(设计)

看了"自己动手设计并实现一个linux嵌入式UI框架"显然没有尽兴,因为还没有看到庐山真面目,那我今天继续,先来说说,我用到了哪些知识背景.如:C语言基础知识,尤其是指针.函数指针.内存分布,linux 基础知识.如消息队列.framebuffer.多线程.多线程同步.等,数据结构.算法(如链表.队列等),window .netframework 框架设计思想,设计模式如 mvc.观察者.单例.工厂等.知识点有点多,每个知识点有机的组合在一起,形成了一个知识网,构成了一个系统.以上提到

自适应大邻域搜索代码系列之(1) - 使用ALNS代码框架求解TSP问题

前言 上次出了邻域搜索的各种概念科普,尤其是LNS和ALNS的具体过程更是描述得一清二楚.不知道你萌都懂了吗?小编相信大家早就get到啦.不过有个别不愿意透露姓名的热心网友表示上次没有代码,遂不过瘾啊~哎,大家先别急,代码有得你们酸爽的-- 不过由于ALNS的代码量实在太大,小编打算把这个做成一个系列来一一为大家讲解,好让小伙伴们彻底把这个算法框架的代码吃透.今天暂时还是先不对代码进行讲解,先来教大家怎么使用ALNS的框架求解一个TSP问题吧~ 环境准备 小编的演示是基于Windows 10 x

4 linux lcd驱动框架分析

4 linux lcd驱动框架 Linux内核中lcd的驱动是基于帧缓冲framebuffer驱动框架设计的.帧缓冲framebuffer框架是在linux2.2.xx以后的版本中为显示设备提供的一种驱动程序接口,它将显示缓冲区framebuffer进行抽象,屏蔽掉硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区framebuffer进行读写和I/O控制操作.Framebuffer机制模仿显卡的功能,将显卡硬件抽象为一系列的数据结构,通过framebuffer的读写实现对显存的操作.

使用EA生成多层次的代码框架

最近工作期间发现了一个非常棒的UML软件[Enterprise Architect UML 建模工具]简称EA,在该软件上绘制框架层面的类之间关系后,可以自动生成相关语言的代码. EA上目前支持的语言有 下面我们将演示,如何生成多层次的python代码框架,EA软件默认的代码是Java,我们需要定制成python,而这个定制在项目内有效,即是对项目属性进行定制. 这里我们建立一个python_hello的项目.顺序是:新建项目=====> 新建增图=====>添加图A=====>添加包=

Linux输入子系统框架分析(1)

在Linux下的输入设备键盘.触摸屏.鼠标等都可以用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层,事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备驱动层将输入事件上报给核心层input.c,核心层找到匹配的事件层,将事件交给事件层处理,事件层处理完后传递到用户空间. 我们最终要搞清楚的是在用户空间调用open和read最终在内核中是怎样处理的,向内核上报的事件又是谁处理的,处理完后是怎样传递到用户空间的? 上面两个图是输入子系统的框架. 下面

Linux模块编程框架

Linux模块编程框架 Linux是单内核系统,可通用计算平台的外围设备是频繁变化的,不可能将所有的(包括将来即将出现的)设备的驱动程序都一次性编译进内核,为了解决这个问题,Linux提出了可加载内核模块(Loadable Kernel Module,LKM)的概念,允许一个设备驱动通过模块加载的方式,在内核运行起来之后"融入"内核,加载进内核的模块和本身就编译进内核的模块一模一样.一个程序在编译的地址的相对关系就已经确定了,运行的时候只是进行简单的偏移,为了使模块加载进内核后能够被放