IO复用select实现

 1 #include<unistd.h>
 2 #include<stdio.h>
 3 #include<sys/select.h>
 4 #include<sys/socket.h>
 5 #include<netinet/in.h>
 6 #include<string.h>
 7 #include<stdlib.h>
 8 #include<assert.h>
 9
10 #define SERVER_IP "127.0.0.1"
11 #define SERVER_PORT 9090
12
13 #define LISTEN_QUEUE_SIZE  5
14
15 void Perror(char *error)
16 {
17     perror(error);
18     exit(1);
19 }
20
21 int Startup(char *ip, short port)
22 {
23     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
24     if(sockfd == -1)
25         Perror("socket");
26
27     short ser_port = port;
28     char *ser_ip = ip;
29
30     struct sockaddr_in addrSer;
31     addrSer.sin_family = AF_INET;
32     addrSer.sin_port = htons(ser_port);
33     addrSer.sin_addr.s_addr = inet_addr(ser_ip);
34
35
36     int yes = 1;
37     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
38
39     socklen_t len = sizeof(struct sockaddr);
40     int res = bind(sockfd, (struct sockaddr*)&addrSer, len);
41     if(res == -1)
42         Perror("bind");
43     res = listen(sockfd, LISTEN_QUEUE_SIZE);
44     if(res == -1)
45         Perror("listen");
46
47     return sockfd;
48 }
49
50
51 ye
 1  #include"utili.h"
 2
 3 //select ip port
 4
 5 #define MAX_CLIENT_NUM 50000
 6
 7 void handler_msg(int sockConn)
 8 {
 9     char buffer[256];
10     recv(sockConn, buffer, 256, 0);
11     printf("cli msg:> %s\n",buffer);
12     send(sockConn, buffer, strlen(buffer)+1, 0);
13 }
14
15
16
17 int main(int argc, char *argv[])
18 {
19     assert(argc == 3);
20     short port = atoi(argv[2]);
21     int sockSer = Startup(argv[1], port);
22
23     int client_fd[MAX_CLIENT_NUM] = {0};
24     fd_set readset;
25
26     int max_sock = sockSer;
27     int conn_num = 0;
28     int i;
29     while(1)
30     {
31         FD_ZERO(&readset);
32         FD_SET(sockSer, &readset);
33         for(i=0; i<MAX_CLIENT_NUM; ++i)
34         {
35             if(client_fd[i] != 0)
36             {
37                 FD_SET(client_fd[i], &readset);
38             }
39         }
40         printf("select waiting......\n");
41         int res = select(max_sock+1, &readset, NULL, NULL, NULL);
42         printf("select wakeup.......\n");
43         if(res == -1)
44         {
45             perror("select");
46             continue;
47         }
48         else if(res == 0)
49         {
50             printf("select Time Out.\n");
51             continue;
52         }
53         else
54         {
55             //1
56             if(FD_ISSET(sockSer, &readset))
57             {
58                 struct sockaddr_in addrCli;
59                 socklen_t len = sizeof(struct sockaddr);
60                 int sockConn = accept(sockSer, (struct sockaddr*)&addrCli, &len);
61                 if(sockConn == -1)
62                 {
63                     printf("Server Accept Client Connect Fail.\n");
64                 }
65                 else
66                 {
67                     printf("Server Accept Client Connect OK.\n");
68                     client_fd[conn_num++] = sockConn;
69
70                     if(sockConn > max_sock)
71                         max_sock = sockConn;
72                 }
73                 continue;
74             }
75
76             for(i=0; i<conn_num; ++i)
77             {
78                 if(FD_ISSET(client_fd[i], &readset))
79                 {
80                     handler_msg(client_fd[i]);
81                 }
82             }
83         }
84
85     }
86
87     return 0;
88 }
时间: 2024-12-18 18:23:16

IO复用select实现的相关文章

UNPv1第六章:IO复用select&amp;poll

有些进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(也就是说输入已准备好被读取,或者描述符已能承受更多的输出),他就通知进程,这个能力称为I/O复用 1.IO模型 5种基本I/O模型 阻塞式I/O 非阻塞式I/O I/O复用(select和poll) 信号驱动式I/O(SIGIO) 异步I/O 一个输入操作通常包括两个不同的阶段 (1)等待数据准备 (2)从内核向进程复制数据 对于一个套接口上的输入操作,第一步一般是等待数据到达网络,当分组到达时,它被拷贝到内

TCP IO复用 select并发服务端 Linux socket编程入门(3)

在写这段代码的时候,发现很多地方容易弄错.select有可能会出错,返回-1. 比如 int FD_ISSET(int fd,fd_set *fdset); void FD_CLR(int fd,fd_set *fdset); void FD_SET(int fd,fd_set *fdset); void FD_ZERO(int fd,fd_set *fdset); 这里的几个宏都是传入指针,而不是值传递. select函数声明如下: int select(int maxfdp1,fd_set

IO复用之——select

一. select 前面提到Linux下的五种IO模型中有一个是IO复用模型,这种IO模型是可以调用一个特殊的函数同时监听多个IO事件,当多个IO事件中有至少一个就绪的时候,被调用的函数就会返回通知用户进程来处理已经ready事件的数据,这样通过同时等待IO事件来代替单一等待一个IO窗口数据的方式,可以大大提高系统的等待数据的效率:而接下来,就要讨论在Linux系统中提供的一个用来进行IO多路等待的函数--select: 二. select函数的用法 首先在使用select之前,要分清在IO事件

[Z] linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO

原文链接:http://blog.csdn.net/colzer/article/details/8169075 IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descriptor(fd,文件描述符).而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符).描述符就是一个数字,指向内核中一个结构体(文件路径,数据

TCP/IP 网络编程 (抄书笔记 5) -- select 和 IO 复用

TCP/IP 网络编程 (抄书笔记 5) – select 和 IO 复用 TCP/IP 网络编程 (抄书笔记 5) – select 和 IO 复用 利用 fork() 生成子进程 可以达到 服务器端可以同时响应多个 客户端的请求, 但是这样做有缺点: 需要大量的运算和内存空间, 每个进程都要有独立的内存空间, 数据交换也很麻烦 (IPC, 如管道) IO 复用: 以太网的总线结构也是采用了 复用技术, 如果不采用, 那么两两之间就要直接通信 网络知识 int server_sock; int

linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descriptor(fd,文件描述符).而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符).描述符就是一个数字,指向内核中一个结构体(文件路径,数据区,等一些属性).那么我们的应用程序对文件的读写就通过对描述符的读写完成. linux将内存分为内核区,用户区.l

【Unix网络编程】chapter6 IO复用:select和poll函数

chapter6 6.1 概述 I/O复用典型使用在下列网络应用场合. (1):当客户处理多个描述符时,必须使用IO复用 (2):一个客户同时处理多个套接字是可能的,不过不叫少见. (3):如果一个TCP服务器既要处理监听套接字,又要处理已连接套接字. (4):如果一个服务器既要处理TCP,又要处理UDP (5):如果一个服务器要处理多个服务或多个协议 IO复用并非只限于网络,许多重要的应用程序也需要使用这项技术. 6.2 I/O模型 在Unix下可用的5种I/O模型的基本区别: (1)阻塞式I

IO复用一select, poll, epoll用法说明

三种IO复用类型 Select系统调用 #include<sys/select.h> int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* execptfds,struct timeval* timeout); #nfds表示监听的文件描述符总数: #readfds,writefds,execptfds分别表示对应的fd_set类型的集合 可以如下定义:fd_set readfds,writefds,execptfds

一次读懂 Select、Poll、Epoll IO复用技术

我们之前采用的多进程方式实现的服务器端,一次创建多个工作子进程来给客户端提供服务.其实这种方式是存在问题的. 可以打个比方:如果我们先前创建的几个进程承载不了目前快速发展的业务的话,是不是还得增加进程数?我们都知道系统创建进程是需要消耗大量资源的,所以这样就会导致系统资源不足的情况. 那么有没有一种方式可以让一个进程同时为多个客户端端提供服务? 接下来要讲的IO复用技术就是对于上述问题的最好解答. 对于IO复用,我们可以通过一个例子来很好的理解它.(例子来自于<TCP/IP网络编程>) 某教室