• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            BLUESKY
            一步一個(gè)腳印向前走

            經(jīng)過(guò)幾天對(duì)I/O復(fù)用這章內(nèi)容的學(xué)習(xí),了解select、pselect、poll函數(shù)

            I/O復(fù)用主要用于有多個(gè)描述字的場(chǎng)合,在前面的回射程序的學(xué)習(xí)當(dāng)中,我們可以發(fā)現(xiàn)客戶(hù)端程序要處理2個(gè)描述字,
            其中一個(gè)是用于處理客戶(hù)端的標(biāo)準(zhǔn)輸入
            另外一個(gè)是用于處理套接口傳遞過(guò)來(lái)的數(shù)據(jù)

            基于上面的情況,我們可以發(fā)現(xiàn)有這樣一種情況,如果服務(wù)端程序提前斷開(kāi),例如輸入ctrl+C,那么客戶(hù)端程序依然阻塞于
            標(biāo)準(zhǔn)輸入,即等待用戶(hù)輸入,但這時(shí)輸入已經(jīng)毫無(wú)意義,因?yàn)榉?wù)器程序已經(jīng)停止工作了;

            這章的幾個(gè)函數(shù)就是用于處理這種情況的,即當(dāng)任何一個(gè)描述字當(dāng)前的狀態(tài)為準(zhǔn)備好,那么程序就可以處理它,而不是一直
            阻塞于未準(zhǔn)備好的描述字

            在unix中有5個(gè)基本的I/O模型
            1、阻塞I/O
            2、非阻塞I/O
            3、I/O復(fù)用
            4、信號(hào)驅(qū)動(dòng)I/O
            5、異步I/O

            我們這章主要用的是I/O復(fù)用(select/poll),其他的I/O模型在這里就不介紹了!
            我們阻塞于select調(diào)用,等待數(shù)據(jù)報(bào)套接口可讀,當(dāng)select返回套接口可讀的條件時(shí),我們調(diào)用recvfrom將數(shù)據(jù)報(bào)拷貝到應(yīng)用緩沖區(qū)中
            使用它的好處是我們可以等待多個(gè)描述字準(zhǔn)備好

            下面簡(jiǎn)單介紹一下select函數(shù)的幾個(gè)參數(shù)說(shuō)明
            int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *errorfds, struct timeval *timeout);
            還是按照書(shū)上說(shuō)的順序簡(jiǎn)單介紹下幾個(gè)參數(shù)的含義
            1、timeout參數(shù)是描述字準(zhǔn)備要花費(fèi)的時(shí)間,有三種取值(NULL,{*,*},{0,0}),具體的可自行查找,就不做詳細(xì)的介紹了
            2、readfds,writefds,errorfds指定我們要讓內(nèi)核測(cè)試讀、寫(xiě)和異常條件所需的描述字,類(lèi)型是集合類(lèi)型的,可以用以下幾個(gè)函數(shù)對(duì)其進(jìn)行操作
                  void FD_CLR(int fd, fd_set *fdset);-->turn off the bit for fd in fd_set
                  int FD_ISSET(int fd, fd_set *fdset);-->is the bit for fd in fd_set?
                  void FD_SET(int fd, fd_set *fdset);-->turn on the bit for fd in fd_set
                  void FD_ZERO(fd_set *fdset);-->clear all bits in fd_set
            3、nfds是指定被測(cè)試的描述字的個(gè)數(shù),它的值是最大描述字的值加1

            下面的表格是摘自書(shū)上的小結(jié)


            其中待處理錯(cuò)誤和TCP外帶數(shù)據(jù)還是有點(diǎn)不理解

            在了解了這個(gè)函數(shù)之后,作者就對(duì)前面的回射程序的客戶(hù)端輸出str_cli進(jìn)行修改,使其能檢測(cè)多個(gè)描述字的狀態(tài),并在服務(wù)器退出后能迅速退出,而不是阻塞在等待標(biāo)準(zhǔn)輸入的輸入

            下面就是幾個(gè)關(guān)鍵的代碼片斷

            fp代表標(biāo)準(zhǔn)輸入的描述字
            sockfd代表套接口的描述字
            rset代表描述字集合

            FD_ZERO(&rset);
            FD_SET(fileno(fp),
            &rset);
            FD_SET(sockfd,
            &rset);

            maxfdp1
            =max(fileno(fp),sockfd)+1;//select的第一個(gè)參數(shù),描述字中最大值加1
            select(maxfdp1,&rset,NULL,NULL,NULL);

            //完成上面的代碼以后就開(kāi)始檢測(cè)各個(gè)描述字的狀態(tài),看其是否可讀
            if(FD_ISSET(fileno(fp),&rset)
            {
              
            //do something
            }

            if(FD_ISSET(sockfd,&rset)
            {
              
            //do something
            }


            下面為了改造程序,使其能夠進(jìn)行批量輸入,即能一次輸入多行,還要了解2個(gè)函數(shù)shutdown和close
            區(qū)別:
            1、close將描述字的訪問(wèn)計(jì)數(shù)減一,僅在計(jì)數(shù)器為0時(shí)關(guān)閉套接口
            2、close終止了數(shù)據(jù)傳送的2個(gè)方向:讀和寫(xiě),而shutdown可以只終止一個(gè)方向的連接,這就是其參數(shù)howto設(shè)置的

            howto的選項(xiàng)有如下幾種:
            1、SHUT_RD     -->關(guān)閉連接的讀的一半
            2、SHUT_WR     -->關(guān)閉連接的寫(xiě)的一半
            3、SHUT_RDWR   -->連接的寫(xiě)一半和讀一半都關(guān)閉
                   

            作者是通過(guò)改造str_cli的函數(shù)來(lái)介紹shutdown和select的使用的,但書(shū)上的例子中少了個(gè)關(guān)鍵字else,導(dǎo)致輸入一行就輸出一行,沒(méi)有批量輸入的現(xiàn)象,查了很長(zhǎng)時(shí)間才找到那個(gè)丟失的else(第12行)

            但是我發(fā)現(xiàn),這個(gè)批量輸入只能進(jìn)行輸入一次操作,當(dāng)我輸入ctrl+d的時(shí)候,輸出了以前輸入的多行,但是程序就退出了(需要改造,思考中)

            這個(gè)程序的主要思想就是,通過(guò)一開(kāi)關(guān)先對(duì)標(biāo)準(zhǔn)輸入進(jìn)行select操作(FD_SET(fileno(fp),&rset)),當(dāng)輸入ctrl+d,開(kāi)關(guān)關(guān)閉,關(guān)閉連接的寫(xiě)這一半(shutdown(sockfd,SHUT_WR);),清除select中對(duì)標(biāo)準(zhǔn)輸入的操作的標(biāo)志(FD_CLR(fileno(fp),&rset);),設(shè)置select對(duì)套接口的操作(FD_SET(sockfd,&rset);).......


            這就是對(duì)select的簡(jiǎn)單介紹和一些應(yīng)用,不能一次寫(xiě)的太多,下次再說(shuō)下如何利用select替代服務(wù)端的fork操作......

            posted on 2007-09-08 09:56 LG 閱讀(385) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): UnixProgram

            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            相冊(cè)

            最新評(píng)論

            久久这里只有精品首页| 欧美精品一区二区精品久久| 欧美色综合久久久久久| 香蕉久久AⅤ一区二区三区| 精品综合久久久久久97| 久久久久久狠狠丁香| 久久婷婷五月综合色99啪ak| 亚洲午夜久久久久久久久电影网 | 99蜜桃臀久久久欧美精品网站 | 狠狠色丁香久久婷婷综合_中| 久久精品综合网| 久久精品国产男包| 国产Av激情久久无码天堂| 青青久久精品国产免费看| 国产精品久久久久久影院| 久久受www免费人成_看片中文| 国产成人精品久久一区二区三区 | 66精品综合久久久久久久| 人妻无码精品久久亚瑟影视| 99久久亚洲综合精品网站| 色综合久久中文字幕无码| 人妻无码久久精品| 国产成人精品久久一区二区三区av | 亚洲国产精品久久电影欧美| 久久精品国产精品亚洲| 久久国产乱子精品免费女| 久久国语露脸国产精品电影| 婷婷久久综合| 久久久亚洲精品蜜桃臀 | 久久精品国产日本波多野结衣| 久久99精品久久久久久水蜜桃| 九九99精品久久久久久| 久久av无码专区亚洲av桃花岛| 免费精品久久天干天干| 久久亚洲精品国产亚洲老地址 | AAA级久久久精品无码区| 精品国产一区二区三区久久| 国产精品久久久久9999高清| 国内精品久久九九国产精品| 久久夜色精品国产亚洲| 国产精品成人99久久久久91gav |