【Linux】多路IO转接问题-select

select:

首先设置一个lfd绑定服务端地址结构,用于监听新的连接。select函数调用,用于对整个fd数组进行监听,该数组最大限制1024,通过遍历,来确定是哪个fd有变化:
1.如果是lfd:那么可能是新的连接进来,就要调用accept阻塞监听获得这个新的连接,将fd加入到数组中;
2.其他fd,有可能是需要断开连接,也有可能是要有数据传输。
在这里插入图片描述

1.#include <stdio.h>  
2.#include <stdlib.h>  
3.#include <unistd.h>  
4.#include <string.h>  
5.#include <arpa/inet.h>  
6.#include <ctype.h>  
7.  
8.#include "wrap.h"  
9.  
10.#define SERV_PORT 6666  
11.  
12.int main(int argc, char *argv[])  
13.{  
14.    int i, j, n, nready;  
15.  
16.    int maxfd = 0;  
17.  
18.    int listenfd, connfd;  
19.  
20.    char buf[BUFSIZ];         /* #define INET_ADDRSTRLEN 16 */  
21.  
22.    struct sockaddr_in clie_addr, serv_addr;  
23.    socklen_t clie_addr_len;  
24.  
25.    listenfd = Socket(AF_INET, SOCK_STREAM, 0);    
26.    int opt = 1;  
27.    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  
28.    bzero(&serv_addr, sizeof(serv_addr));  
29.    serv_addr.sin_family= AF_INET;  
30.    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
31.    serv_addr.sin_port= htons(SERV_PORT);  
32.    Bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));  
33.    Listen(listenfd, 128);  
34.      
35.  
36.    fd_set rset, allset;                            /* rset 读事件文件描述符集合 allset用来暂存 */  
37.  
38.    maxfd = listenfd;  
39.  
40.    FD_ZERO(&allset);  
41.    FD_SET(listenfd, &allset);                                  /* 构造select监控文件描述符集 */  
42.  
43.    while (1) {     
44.        rset = allset;                                          /* 每次循环时都从新设置select监控信号集 */  
45.        nready = select(maxfd+1, &rset, NULL, NULL, NULL);  
46.        if (nready < 0)  
47.            perr_exit("select error");  
48.  
49.        if (FD_ISSET(listenfd, &rset)) {                        /* 说明有新的客户端链接请求 */  
50.  
51.            clie_addr_len = sizeof(clie_addr);  
52.            connfd = Accept(listenfd, (struct sockaddr *)&clie_addr, &clie_addr_len);       /* Accept 不会阻塞,因为已经知道要有连接了,所以直接连接 */  
53.  
54.            FD_SET(connfd, &allset);                            /* 向监控文件描述符集合allset添加新的文件描述符connfd */  
55.  
56.            if (maxfd < connfd)  
57.                maxfd = connfd;  
58.  
59.            if (0 == --nready)                                  /* 只有listenfd有事件, 后续的 for 不需执行 */  
60.                continue;  
61.        }   
62.  
63.        for (i = listenfd+1; i <= maxfd; i++) {                 /* 检测哪个clients 有数据就绪 */  
64.  
65.            if (FD_ISSET(i, &rset)) {  
66.  
67.                if ((n = Read(i, buf, sizeof(buf))) == 0) {    /* 当client关闭链接时,服务器端也关闭对应链接 */  
68.                    Close(i);  
69.                    FD_CLR(i, &allset);                        /* 解除select对此文件描述符的监控 */  
70.  
71.                } else if (n > 0) {  
72.  
73.                    for (j = 0; j < n; j++)  
74.                        buf[j] = toupper(buf[j]);  
75.                    Write(i, buf, n);  
76.                }  
77.            }  
78.        }  
79.    }  
80.  
81.    Close(listenfd);  
82.  
83.    return 0;  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值