(二)TCP客戶端/服務器通信------select函數

(一)select函數

該函數允許進程指示內核等待多個事件中的任何一個發生,並只在有一個或多個事件發生或經歷一段指定的時間後才喚醒它。也就是說,我們調用select告知內核對哪些描述符(就讀、寫或異常條件)感興趣以及等待多長時間。我們感興趣的描述符不侷限於套接字,任何描述符都可以使用select來測試。

(1)參數:

1. timeout:它告知內核等待所指定描述符中的任何一個就緒可花的最長時間。


    1)永遠等下去:僅在有一個描述符準備好I/O才返回。空指針。

    2)等待一段固定時間:在固定時長內有準備好的I/O返回,或到達固定時長時返回。

    3)根本不等待:論詢。設置爲0.

前兩種情形的等待通常會被進程在等待期間捕獲的信號中斷,並從信號處理函數返回。


2. readset、writeset和exceptset:指定我們要讓內核測試讀、寫和異常條件的描述符。

select使用描述符集,通常是一個整數數組,其中每個整數中的每一位對應一個描述符。舉例來說,假設使用32位整數,那麼該數組的第一個元素對應於描述符0-31,第二個元素對應於描述符32-63位,以此類推。所有這些實現細節都與應用程序無關,它們隱藏在名爲fd_set的數據類型和以下四個宏中:

描述符集的初始化非常重要,因爲作爲自動變量分配的一個描述符集如果沒有初始化,那麼可能發生不可預期的結果。

select函數修改由指針readset、writeset和exceptset所指向的描述符,因而這三個參數都是值-結果參數。調用該函數時,我們指定所關心的描述符的值,該函數返回時,結果將指示哪寫描述符已就緒。該函數返回後,我們用FD_ISSET宏來測試fd_set數據類型中的描述符。描述符集內任何與未就緒描述符對應的位返回時均清0.爲此,每次重新調用select函數時,我們都得再次把所有描述符集內所關心的位均置位1.


3.    maxfdp1:指定待測試的最大描述符,它的值是待測試的最大描述符加1

maxfdp1參數迫使我們計算出所關心的最大描述符並告知內核該值。存在這個參數以及就算其值的額外負擔純粹是爲了效率原因。

(2)返回:返回值表示跨所有描述符集的已就緒的總位數。

如果在任何描述符就緒之前定時器到時,那麼返回0.返回1表示出錯(這個可能發生的,譬如本函數被一個所捕獲的信號中斷)。


(3)描述符就緒條件

(二)shutdown函數

在批量數據傳輸中,標準輸入中的EOF並不意味着我們同時也完成了從套接字的讀入:可能仍有請求在去服務器的路上,或者仍有應答在返回客戶的路上。

我們需要的是一種關閉TCP連接其中一半的方法。也就是說,我們想給服務器發送一個FIN,告訴它我們已經完成了數據發送,但是仍然保持套接字描述符打開以便讀取。這就需要shutdown函數完成。


(三)pselect函數

pselect函數是select函數的升級版。POSIX定義的pselect函數把時間精度升級到納米級別,並採用一個指向信號集的指針作爲它的一個新參數。當有信號量需要捕捉時,該參數能夠讓我們避免競爭條件。

pselect相對於通常的select有兩個變化:

(1)pselect使用timespec結構,而不使用timeval結構。


(2)pselect函數增加了第六個參數:一個指向信號掩碼的指針。該參數允許程序先禁止遞交某些信號,再測試由這些當前被禁止信號的信號處理函數設置的全局變量,然後調用pselect,告訴它重新設置信號掩碼。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章