UNPv1第十三章 高階IO

2021-07-11 10:51:17 字數 2308 閱讀 2999

涉及套接字上的i/o操作設定超時的方法有三種方法:

呼叫alarm,在到達指定時間時產生sigalrm訊號

使用select阻塞在等待i/o上,select內部有乙個時間限制,以此代替在read或write呼叫上阻塞

使用新的so_rcvtimeo和so_sndtimeo套接字選項

前兩種技術可以用於任何描述字,而第三種只能用於套介面描述字。

這兩個函式和標準的read和write函式都類似,不過多了乙個附加引數

#include 

sszie_t recv(int sockfd, void * buff, size_t nbytes, int flags);

ssize_t send(int sockfd, void * buff, size_t nbytes, int flags);

//返回: 成功返回讀入或寫出的位元組數,出錯返回-1

flag在設計上存在乙個基本問題:它是按值傳遞的,而不是值-結果引數,因此它只能從程序向核心傳遞標誌,核心不能向程序傳遞標誌。

#include 

ssize_t readv(int filedes, const

struct iovec * iov, int iovcnt);

ssize_t writev(int filedes, const

struct iovec * iov, int iovcnt);

//返回: 讀到或寫出的位元組數,出錯時為-1

兩個函式的第二個引數都是乙個指向iovec結構的陣列的指標,在

struct iovec
readv和writev函式可以用於任何描述字,不僅限於套介面描述字,而且writev是乙個原子操作。

這兩個函式是最通用的i/o函式,實際上,可以用recvmsg代替read, readv, recv, recvfrom. 類似的,各種輸出函式可以用sendmsg取代。

#include 

ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags);

ssize_t sendmsg(int sockfd, struct msghdr * msg, int flags);

//返回: 成功時為讀入或寫出的位元組數,出錯時為-1

兩個函式把大部分引數都包裝到乙個msghdr結構中:

struct msghdr ;
輔助資料(ancillary data)可以通過sendmsg和recvmsg這兩個函式,使用msghdr結構中的msg_contorl和msg_controllen成員傳送和接收。

輔助資料的另一種叫法是控制資訊(control information)

輔助資料是乙個或多個輔助資料物件組成,每個物件由乙個cmsghdr結構開頭,該結構在

struct cmsghdr ;
下圖為在unix域套接字上的cmsghdr結構:

在不讀出資料的情況下,如何知道乙個套介面的接收佇列中有多少資料可讀呢?有三種方法:

如果在沒有資料可讀時還有其他事情要做,為了不阻塞在核心中,可以使用非阻塞i/o

如果想檢查一下資料而使資料仍留在接收佇列中,可以使用msg_peek標誌。如果想這樣做,但又不能肯定是否有資料可讀,可以把這個標誌和非阻塞套介面相結合,或與msg_dontwait標誌結合使用。

一些實現支援ioctl的fionread命令

標準i/o庫執行三種緩衝:

完全緩衝意味著只有在以下情況時才進行i/o:緩衝區滿,程序明確地呼叫fflush或程序呼叫exit終止。標準i/o緩衝區大小通常為8192位元組。

行緩衝意味著在以下情況時進行i/o:遇到乙個換行符,程序呼叫fflush或程序呼叫exit終止。

不緩衝意味著每次呼叫標準i/o輸出函式時都進行i/o

大多數unix中標準i/o庫的實現遵循了以下規則:

標準錯誤輸出總是不緩衝。

標準輸入和標準輸出是全緩衝的。除非他們是乙個終端裝置,那樣的話他們是行緩衝。

其他的流都是全緩衝的,除非他們是乙個終端裝置,那樣的話他們是行緩衝。

既然套介面不是終端裝置,上面str_echo函式的問題就在於輸出流(fpout)是全緩衝的。

有兩種解決方法:呼叫setvbuf將輸出流強制成行緩衝的,或者在每次fputs之後呼叫fflush強制輸出回射行。

UNPv1第二十三章 執行緒

在傳統的unix模型中,當乙個程序需要由另乙個實體執行某件事時,該程序派生 fork 乙個子程序,讓子程序去進行處理。unix下的大多數網路伺服器程式都是這麼編寫的,這在我們的併發服務程式例子中可以看出 父程序接收連線,派生子程序,子程序處理與客戶的互動。雖然這種模式很多年來使用的很好,但是fork...

Mysql學習 第十三章 高階聯結

sql 除了可以對列名和計算字段使用別名,還允許給表名起別名。縮短 sql語句 允許在一條 select 語句中多次使用相同的表。select cust name,cust contact from customers as c,orders as o,orderitems as oi where ...

UNPv1第十八章 廣播

單播ip資料報僅有通過目的ip位址指定的單個主機接受,子網上的其他主機均不受影響 子網上所有未參加相應廣播應用的所有機也必須沿協議棧一路向上完整的處理收取udp廣播資料報,直至該資料報經歷udp層時被丟棄為止 include unp.h static void recvfrom alarm int ...