unix下共有5種i/o模型:
阻塞式i/o
非阻塞式i/o
i/o復用(select和poll)
訊號驅動式i/o(sigio)
非同步i/o(posix的aio_系列函式)
同步i/o與非同步i/o:
同步i/o操作導致請求程序阻塞,直到i/o操作完成。前4種模型都是同步i/o模型,因為其中真正的i/o操作將阻塞程序。
非同步i/o操作不導致請求程序阻塞。
select函式讀就緒條件:
該套接字接收緩衝區中的資料位元組數大於等於套接字接收緩衝區低水位標記的當前大小。對上述套接字執行讀操作不會阻塞並將返回乙個大於0的值。
該連線讀半部關閉(也就是接收了fin的tcp連線)。對這樣的套接字的讀操作將不阻塞並返回0(也就是返回eof)。
該套接字是乙個監聽套接字並且已完成連線數不為0。
其上有乙個套接字錯誤待處理。
select函式寫就緒條件:
該套接字傳送緩衝區中的可用空間位元組數大於等於套接字傳送緩衝區低水位標記的當前大小,並且或者該套接字已連線,或該套接字不需要連線(例如udp套接字)。
該連線的寫半部關閉。對這樣的套接字的寫操作將產生sigpipe訊號。
使用非阻塞式connect的套接字已經建立連線,或者connect已經以失敗返回。
其上有乙個套接字錯誤待處理。
當某個套接字上發生錯誤時,它將由select標記為既可讀又可寫。
這裡要對讀寫操作的一些特點進行總結:
finrst
讀對這樣的套接字的讀操作將不阻塞並返回0(也就是返回eof)
從已經接收到rst的套接字中讀取資料,函式將返回econnreset(「connection reset by peer」,對方復位連線錯誤)。
寫向已經接收到fin的套接字中寫入資料,不會引發問題,但會引發對端傳送rst
向接收到rst的套接字中寫入資料,核心會向程序傳送sigpipe訊號,並使程序終止。
在批量方式下,標準輸入中的eof並不意味著我們同時也完成了從套接字的讀入;可能仍有請求在去往伺服器的路上,或者仍有應答在返回客戶的路上。
對於上述問題的解決方法是關閉tcp連線其中的一半。
終止網路連線的通常方法是呼叫close函式。不過close有兩個限制,卻可以使用shutdown來避免。
close把描述符引用計數減1,直到為0時才關閉套接字。但shutdown可以直接激發tcp的正常終止序列。
close終止讀和寫兩個方向的資料傳送。
函式原型如下:
#include extern int shutdown (int __fd, int __how) __throw;
__how有以下三種情況:
shut_rd,關閉連線的讀一半。對乙個tcp套接字呼叫shutdown函式後,由該套接字接收的來自對端的任何資料都被確認,並悄悄丟棄。
shut_wr,關閉連線的寫一半。激發正常終止序列。
shut_rdwr,連線的讀半部和寫半部都關閉。
這裡先給大家總結select與poll函式的第乙個區別,也是我自己總結的。
select函式在使用時通過fd_set型別的資料對其中等待的描述符進行記錄,但對這一結構並不是直接對應於每乙個描述符,我們還需要專門的函式對這一型別進行操作,因此在使用select函式時還需要使用乙個專門的陣列用於記錄相應的描述符。
但poll函式通過struct pollfd對等待的描述符進行記錄,這一結構的第乙個字段直接記錄了這一描述符,因此不再需要乙個專門的陣列用於存放描述符。
《UNIX網路程式設計 卷2》讀書筆記(四)
include globals include unpipc.h define maxnitems 1000000 define maxnthreads 100 globals shared by threads int nitems read only by producer and consum...
Unix網路程式設計讀書筆記(二)
套接字位址結構 typedef uint32 t in addr t struct in addr struct sockaddr in 在使用結構前總是把整個結構置零,是由於sin zero欄位沒有任何作用,只需置零即可。為了是套接字函式在處理位址時具有一定的通用性,套接字函式還定義了通用套接字位...
Unix網路程式設計讀書筆記(五)
使用udp編寫的一些常見的應用程式有 dns 網域名稱系統 nfs 網路檔案系統 和snmp 簡單網路關係協議 udp協議的通訊函式分別是sendto與recvfrom函式,函式原型如下 include extern ssize t recvfrom int fd,void restrict buf...