socket可讀可寫就緒條件


參考 《UNIX 網絡編程卷1》中的《第6章 I/O復用》

 

一、 滿足下列四個條件中的任何一個時,一個套接字准備好讀。

  1. 該套接字接收緩沖區中的數據字節數大於等於套接字接收緩存區低水位。對於TCP和UDP套接字而言,緩沖區低水位的值默認為1。那就意味着,默認情況下,只要緩沖區中有數據,那就是可讀的。我們可以通過使用SO_RCVLOWAT套接字選項(參見setsockopt函數)來設置該套接字的低水位大小。此種描述符就緒(可讀)的情況下,當我們使用read/recv等對該套接字執行讀操作的時候,套接字不會阻塞,而是成功返回一個大於0的值(即可讀數據的大小)。
  2. 該連接的讀半部關閉(也就是接收了FIN的TCP連接)。對這樣的套接字的讀操作,將不會阻塞,而是返回0(也就是EOF)。
  3. 該套接字是一個listen的監聽套接字,並且目前已經完成的連接數不為0。對這樣的套接字進行accept操作通常不會阻塞。
  4. 有一個錯誤套接字待處理。對這樣的套接字的讀操作將不阻塞並返回-1(也就是返回了一個錯誤),同時把errno設置成確切的錯誤條件。這些待處理錯誤(pending error)也可以通過指定SO_ERROR套接字選項調用getsockopt獲取並清除。

 

二、滿足下列四個條件中的任何一個時,一個套接字准備好寫。

  1. 該套接字發送緩沖區中的可用空間字節數大於等於套接字發送緩存區低水位標記時,並且該套接字已經成功連接(UDP套接字不需要連接)。對於TCP和UDP而言,這個低水位的值默認為2048,而套接字默認的發送緩沖區大小是8k,這就意味着一般一個套接字連接成功后,就是處於可寫狀態的。我們可以通過SO_SNDLOWAT套接字選項(參見setsockopt函數)來設置這個低水位。此種情況下,我們設置該套接字為非阻塞,對該套接字進行寫操作(如write,send等),將不阻塞,並返回一個正值(例如由傳輸層接受的字節數,即發送的數據大小)。
  2. 該連接的寫半部關閉(主動發送FIN包的TCP連接)。對這樣的套接字的寫操作將會產生SIGPIPE信號。所以我們的網絡程序基本都要自定義處理SIGPIPE信號。因為SIGPIPE信號的默認處理方式是程序退出。
  3. 使用非阻塞的connect套接字已建立連接,或者connect已經以失敗告終。即connect有結果了。
  4. 有一個錯誤的套接字待處理。對這樣的套接字的寫操作將不阻塞並返回-1(也就是返回了一個錯誤),同時把errno設置成確切的錯誤條件。這些待處理的錯誤也可以通過指定SO_ERROR套接字選項調用getsockopt獲取並清除。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM