多路复用I/O:一个执行体监视多个文件描述符对象的状态是否改变,一旦改变通知其他执行体来实现。

基本思想:

1、 先构造一张有关描述符的表,然后调用一个函数,当这些文件描述符中的一个或者多个已准备好进行I/O时函数才返回

2、 函数返回时告诉进程那个描述符已准备就绪,可以进行I/O操作。

Select(int n,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct timeval *timeout);

注意两点:

1、 select函数返回之前会将集合中状态未改变的fd清除

2、 返回值为状态改变的文件描述符对象的个数。

3、 Select阻塞时内部会产生一个线程盯着描述符对象的状态改变。

参数:n:maxfd,所有监控的文件描述符中值最大的加1;

Read_fds:是否可读的文件描述符集

Write_fds:是否可写的文件描述符集

Except_fds:出错的文件描述符集

Timeout:如果设置为NULL,则会一直阻塞,直到文件描述符的状态改变

Struct timeval

{

Long tv_sec;

Long tv_usec;

} ;

文件描述符的几个宏:

FD_ZERO(fd_set *fdset):清空文件描述符集

FD_SET(int fd,fd_set *fdset):将fd加入到fd_set集中

FD_ISSET(int fd,fd_set*fdset):判断fd是否在fdset中

FD_CLR(fd,fd_set *fdset);将fd从fdset集中清除

Select函数使用范例(功能:本例使用的是tcp,select监听标准输入是否准备好字符串可读然后发送和socketfd是否可读,然后接受,实现以简单的qq通信)

客户端:
#include<stdio.h>
#include<pthread.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include<strings.h>
#include<sys/types.h>
#include<sys/socket.h>
int main()
{
int socketfd,ret;
fd_set fd;
FD_ZERO(&fd);
FD_SET(,&fd); socketfd = socket(PF_INET,SOCK_STREAM,);
FD_SET(socketfd,&fd);
ret = select(socketfd+,&fd,NULL,NULL,NULL);
struct sockaddr_in saddr;
memset(&saddr,,sizeof(saddr));
saddr.sin_family = PF_INET;
saddr.sin_port = htons();
saddr.sin_addr.s_addr = inet_addr("192.168.1.46"); if(connect(socketfd,(struct sockaddr *)&saddr,sizeof(struct sockaddr))<) perror("connect() error!\n");
char buf[],buf1[];
while()
{
bzero(buf,);
bzero(buf1,); FD_SET(,&fd);
FD_SET(socketfd,&fd);
ret = select(socketfd+,&fd,NULL,NULL,NULL);
if(FD_ISSET(socketfd,&fd))
{
if(recv(socketfd,buf1,sizeof(buf1),)<)
perror("recv() error!\n");
printf("%s",buf1);
continue;
}
if(FD_ISSET(,&fd))
{
// printf("please input:\n");
fgets(buf,,stdin);
if(send(socketfd,buf,strlen(buf),)<)
perror("send() error!\n");
continue;
} }
}
服务器端:
#include<stdio.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<pthread.h>
#include<strings.h>
int main()
{
int fds[];
int maxfd = -;
int socketfd = socket(PF_INET,SOCK_STREAM,);
if(socketfd<maxfd)
maxfd = socketfd;
struct sockaddr_in saddr;
memset(&saddr,,sizeof(saddr));
saddr.sin_family = PF_INET;
saddr.sin_port = htons();
saddr.sin_addr.s_addr = inet_addr("192.168.193.2");
int newsocketfd;
int n = ;
setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int));
if(bind(socketfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr_in))<)
perror("bind() error!\n"); if(listen(socketfd,)<)
perror("listen() error!\n");
struct sockaddr_in caddr;
int s = sizeof(struct sockaddr);
newsocketfd=accept(socketfd,(struct sockaddr*)&caddr,&s);
fd_set fd;
FD_ZERO(&fd);
int ret;
char buf[],buf1[];
int i;
int rsize;
printf("hello\n");
while()
{
bzero(buf,);
bzero(buf1,);
// printf("hello\n");
FD_SET(,&fd);
// printf("hello\n");
FD_SET(newsocketfd,&fd);
// printf("hello\n");
select(newsocketfd+,&fd,NULL,NULL,NULL);
if(FD_ISSET(newsocketfd,&fd))
{
// printf("hello\n");
if(recv(newsocketfd,buf1,sizeof(buf1),)<)
perror("recv() error!\n");
printf("%s",buf1);
// printf("hello\n");
continue;
} if(FD_ISSET(,&fd))
{
fgets(buf,,stdin);
if(send(newsocketfd,buf,strlen(buf),)<)
perror("send() error!\n");
continue;
}
}
close(socketfd);
close(newsocketfd); }

多路复用select的更多相关文章

  1. 第五十五节,IO多路复用select模块加socket模块,伪多线并发

    IO多路复用select模块加socket模块,伪多线并发,并不是真正的多线程并发,实际通过循环等待还是一个一个处理的 IO多路复用,lo就是文件或数据的输入输出,IO多路复用就是可以多用户操作 IO ...

  2. Linux IO多路复用 select

    Linux IO多路复用 select 之前曾经写过简单的服务器,服务器是用多线程阻塞,客户端每一帧是用非阻塞实现的 后来发现select可以用来多路IO复用,就是说可以把服务器这么多线程放在一个线程 ...

  3. io多路复用-select()

    参照<Unix网络编程>相关章节内容,实现了一个简单的单线程IO多路复用服务器与客户端. 普通迭代服务器,由于执行recvfrom则会发生阻塞,直到客户端发送数据并正确接收后才能够返回,一 ...

  4. Linux 多路复用 select / poll

    多路复用都是在阻塞模式下有效! linux中的系统调用函数默认都是阻塞模式,例如应用层读不到驱动层的数据时,就会阻塞等待,直到有数据可读为止. 问题:在一个进程中,同时打开了两个或者两个以上的文件,读 ...

  5. I/O多路复用select/poll/epoll

    前言 早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个.因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll.现代操作系统中,线程数已经得到了 ...

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

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

  7. 【操作系统】I/O多路复用 select poll epoll

    @ 目录 I/O模式 I/O多路复用 select poll epoll 事件触发模式 I/O模式 阻塞I/O 非阻塞I/O I/O多路复用 信号驱动I/O 异步I/O I/O多路复用 I/O 多路复 ...

  8. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  9. Python实战之IO多路复用select的详细简单练习

    IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. select   它通过一个select()系统调用来 ...

随机推荐

  1. Runtime之NSCoding的自动归档、接档

    为什么要有Runtime的NSCoding的自动归档.接档 大家所熟知的方法 //归档方法 - (void)encodeWithCoder:(NSCoder *)aCoder { //当学生被归档,学 ...

  2. Oracle_where子句

    Oracle_where子句 --1.查询员工名为'SMITH'的信息 select * from emp where ename = 'SMITH';   --2.查询在1980/12/17入职的员 ...

  3. [随笔] 简单操作解决Google chrome颜色显示不正常的情况

    最近在用Linuxmint 真的是极友好的桌面Linux啊,然后用最新的Linuxmint自带的Firefox浏览器上网,发现颜色都变成了红色黄色变绿色,以为是显卡的问题,搞了一阵,无果.果断换Goo ...

  4. dede后台登陆后一片空白的解决办法汇总

    dede后台登陆后一片空白的第一种解决办法: 找到:include/common.inc.php文件,打开,查找程序代码://error_reporting(E_ALL);error_reportin ...

  5. dede:list及dede:arclist 按权重排序的方法

    有时我们需要做文章排名,比如指定第一名到第三名在前面,这样就用到这个权重排序方法.稍改下就可以完美支持.. dede:list 的方法 1 找到"根目录\include\arc.listvi ...

  6. Django权限机制的实现

    Django权限机制的实现 1. Django权限机制概述 权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮.因此,基于Django的开发 ...

  7. 2018/1/28 每日一学 单源最短路的SPFA算法以及其他三大最短路算法比较总结

    刚刚AC的pj普及组第四题就是一种单源最短路. 我们知道当一个图存在负权边时像Dijkstra等算法便无法实现: 而Bellman-Ford算法的复杂度又过高O(V*E),SPFA算法便派上用场了. ...

  8. php实现监控在线服务应用程序小栗子

    下面我就给大家举个栗子(例子) 某单位需要实现监控服务器状态,和监控服务器应用网站,还有需要监控服务器的中间件,数据库状态监控.听到这个任务是不是恨透头疼,这想起来是不是头疼.还好有系统可用,但是我现 ...

  9. JS 实现百度搜索功能

    今天我们来用JS实现百度搜索功能,下面上代码: HTML部分: <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  10. 字体类形:font-family, font-style

    语法:{font-family:字体1,字体2,字体3,...} 作用:调用客户端字体 font-family: "Lantinghei SC","Microsoft Y ...