欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

I/O多路轉(zhuǎn)接之select

I/O多路轉(zhuǎn)接之select(只負責等)

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供赤坎網(wǎng)站建設(shè)、赤坎做網(wǎng)站、赤坎網(wǎng)站設(shè)計、赤坎網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、赤坎企業(yè)網(wǎng)站模板建站服務(wù),十余年赤坎做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

系統(tǒng)提供select函數(shù)來實現(xiàn)多路復用輸入/輸出模型。

 I/O多路轉(zhuǎn)接之select

傳向select的參數(shù)告訴內(nèi)核:

1)我們所關(guān)心的文件描述符。

參數(shù)nfds是需要監(jiān)視的最大的文件描述符值+1;

2)對每個描述符,我們所關(guān)心的狀態(tài)。

rdset,wrset,exset分別對應(yīng)于需要檢測的可讀文件描述符的集合,可寫文件描述符的集合及異常文件描述符的集合。

監(jiān)視的文件描述符分為三類set,每一種對應(yīng)等待不同的事件。readfds中列出的文件描述符被監(jiān)視是否有數(shù)據(jù)可供讀?。ㄈ绻x取操作完成則不會 阻 塞)。writefds中列出的文件描述符則被監(jiān)視是否寫入操作完成而不阻塞后,exceptfds中列出的文件描述符則被監(jiān)視是否發(fā)生異常,或者無 法控制的數(shù)據(jù)是否可用(這些狀態(tài)僅僅應(yīng)用于套接字)。這三類set可以是NULL,這種情況下select()不監(jiān)視這一類事件。

下面的宏提供了處理這三種描述詞組的方式:

FD_ZERO移除指定set中的所有文件描述符。每一次調(diào)用select()之前都應(yīng)該先調(diào)用它;

FD_CLR則從指定的set中移除一個文件描述符;

FD_SET添加一個文件描述符到指定的set中;

FD_ISSET測試一個文件描述符是否指定set的一部分。如果文件描述符在set中則返回一個非0整數(shù),不在則返0,F(xiàn)D_ISSET在調(diào)用select() 返回之后使用,測試指定的文件描述符是否準備好相關(guān)動作。

3)我們要等待多長時間。(我們可以等待無限長的時間,等待固定的一段時間,或者根本就不等待)

timeout參數(shù)是一個指向timeval結(jié)構(gòu)體的指針,timeval定義如下:

 I/O多路轉(zhuǎn)接之select

struct timeval結(jié)構(gòu)用于描述一段時間長度,如果在這個時間內(nèi),需要監(jiān)視的描述符沒有事件發(fā)生則函數(shù)返回,返回值為0。

從 select函數(shù)返回后,內(nèi)核告訴我們以下信息:

1)已經(jīng)做好準備的描述符的個數(shù)。

2)對于三種條件哪些描述符已經(jīng)做好準備。(讀,寫,異常)

執(zhí)成功則返回件描述詞狀態(tài)已改變的個數(shù);如果返回0代表在描述詞狀態(tài)改變前已超過timeout時間,沒有返回;
當有錯誤發(fā)時則返回-1,錯誤原因存于errno,此時參數(shù)readfds,writefds,exceptfds和timeout的值變成不可預測。錯誤值可能為:EBADF 件描述詞為效的或該件已關(guān)閉 ,EINTR 此調(diào)被信號所中斷 EINVAL 參數(shù)n 為負值,ENOMEM 核內(nèi)存不。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>


int fds[64];
const fds_nums=sizeof(fds)/sizeof(fds[0]);
static int startup(const char* _ip,int _port)
{
    int sock=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0)
    {
        perror("socket");
        exit(2);
    }
    int opt=1;
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    struct sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_port=htons(_port);
    local.sin_addr.s_addr=inet_addr(_ip);
    if(bind(sock,(struct sockaddr*)&local, sizeof(local))<0)
    {
        perror("bind");
        exit(3);
    }
    if(listen(sock,5)<0)
    {
        perror("listen");
            exit(4);
    }
    return sock;
}
static void usage(const char* _proc)
{
    printf("Usage:%s[IP] [PORT]\n",_proc);
}
int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        usage(argv[0]);
        exit(1);
    }
    int i=0;
    for(i=0;i<fds_nums;++i)
    {
        fds[i]=-1;
    }

    int  listen_sock=startup(argv[1],atoi(argv[2]));
    fd_set rset;
    FD_ZERO(&rset);
    FD_SET(listen_sock,&rset);

    fds[0]=listen_sock;

    int done=0;
    while(!done)
    {
        int max_fd=-1;
        for(i=0;i<fds_nums;++i)
        {
            if(fds[i]>0)
            {
                FD_SET(fds[i],&rset);
                max_fd=max_fd<fds[i]?fds[i]:max_fd;
            }
        }

        struct timeval timeout={0,0};
        switch(select(max_fd+1,&rset,NULL,NULL,NULL/*&timeout*/))
        {
            case 0:
                printf("timeout..\n");
                break;
            case 1:
                perror("select");
                break;
            default:
                for(i=0;i<fds_nums;++i)
                {
                    if(i=0&& FD_ISSET(listen_sock,&rset))
                    {
                        struct sockaddr_in peer;
                        socklen_t len=sizeof(peer);
                        int new_fd=accept(listen_sock,(struct sockaddr*)&peer,&len);
                        if(new_fd>0)
                        {
                            printf("get a new client:socket->%s:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
                            int j=0;
                            for(j=0;j<fds_nums;j++)
                            {                            
                                if(fds[i]==-1)
                                {
                                    fds[j]=new_fd;
                                    break;
                                }
                            }
                            if(j==fds_nums)
                            {
                                close(new_fd);
                            }
                        }
                        else
                        {
                            if(FD_ISSET(fds[i],&rset))
                            {
                                char buf[1024];
                                memset(buf,'\0',sizeof(buf));
                                ssize_t _s=read(fds[i],buf,sizeof(buf)-1);
                                if(_s>0)
                                {
                                    printf("client#  %s\n",buf);
                                }
                                else if(_s==0)
                                {
                                printf("client close...\n");
                                close(fds[i]);
                                }
                                else
                                {
                                    perror("read");
                                }
                            }
                        }
                    }
                }
                break;
        }
    }
return 0;
}

select優(yōu)點:

(1)相較于之前多線程的方法,使用select不用創(chuàng)建線程,更方便

(2)select目前幾乎在所有的平臺上都支持,其良好跨平臺支持也是它的一個優(yōu)點 

select缺點:

(1)每次調(diào)用select,都需要把fd集合從用戶態(tài)拷貝到內(nèi)核態(tài),這個開銷在fd很多時會很大 

(2)同時每次調(diào)用select都需要在內(nèi)核遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大 

(3)能夠監(jiān)視的文件描述符的數(shù)量存在最大限制,在Linux上一般為1024,因為它依賴于文件系統(tǒng)

(4)select()所維護的文件描述符的數(shù)據(jù)結(jié)構(gòu),隨著文件描述符數(shù)量的增大,其復制的開銷也線性增長。

(5)由于網(wǎng)絡(luò)響應(yīng)時間的延遲使得大量TCP連接處于非活躍狀態(tài),但調(diào)用select()會對所有socket進行一次線性掃描,這也會有一些開銷


網(wǎng)站標題:I/O多路轉(zhuǎn)接之select
文章網(wǎng)址:http://chinadenli.net/article36/gphgsg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊軟件開發(fā)、小程序開發(fā)電子商務(wù)、微信公眾號、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
亚洲高清中文字幕一区二三区| 午夜精品成年人免费视频| 中文字幕高清不卡一区| 东北老熟妇全程露脸被内射| 国产对白老熟女正在播放| 午夜午夜精品一区二区| 丰满人妻一二三区av| 国产精品视频一区麻豆专区| 国产a天堂一区二区专区| 暴力三级a特黄在线观看| 国产在线一区中文字幕| 一级片黄色一区二区三区| 一区二区三区四区亚洲另类| 国产色第一区不卡高清| 亚洲精品国产第一区二区多人| 久久综合亚洲精品蜜桃| 日韩无套内射免费精品| 九九热这里有精品20| 国产国产精品精品在线| 国产精品伦一区二区三区在线| 人妻少妇久久中文字幕久久| 欧美日韩精品一区二区三区不卡| 欧美特色特黄一级大黄片| 99久久精品免费看国产高清| 日韩欧美在线看一卡一卡| 男人的天堂的视频东京热| 国产成人精品视频一区二区三区 | 国产二级一级内射视频播放| 91精品国产综合久久不卡| 精品国产亚洲免费91| 亚洲视频一区自拍偷拍另类| 国产欧美日韩综合精品二区| 久久福利视频视频一区二区 | 在线免费观看一二区视频| 91精品国产综合久久不卡| 91亚洲国产—区=区a| 日韩一区二区三区在线日| 国产欧美高清精品一区| 成人国产激情福利久久| 色婷婷丁香激情五月天| 亚洲av熟女国产一区二区三区站|