Socket,非阻塞,fcntl


一、fcntl

  用以下方法將socket設置成為非阻塞方式

  int  flags = fcntl(socket,F_GETFL,0);

  fcntl(socket,F_SETFL,flags|O_NONBLOCK);

 

  將非阻塞的設置回阻塞可以用

  int  flags = fcntl(socket,F_GETFL,0);

  fcntl(socket,F_SETFL,flags&~O_NONBLOCK);

------------------------------------------------------------------------

  #include <unistd.h>

  #include <fcntl.h>

 

  int fcntl(int fd, int cmd);

  int fcntl(int fd, int cmd, long arg);

  int fcntl(int fd, int cmd, struct flock *lock);

 

  [描述] fcntl()針對(文件)描述符提供控制。參數fd是被參數cmd操作(如下面的描述)的描述符。針對cmd的值,fcntl能夠接受第三個參數int arg。

 

  Cmd值的F_GETFL和F_SETFL:  
  

  F_GETFL    取得fd的文件狀態標志,如同下面的描述一樣(arg被忽略),在說明open函數時,已說明了文件狀態標志。不幸的是,三個存取方式標志

        (O_RDONLY ,O_WRONLY , 以及O_RDWR)並不各占1位。(這三種標志的值各是0 , 1和2,由於歷史原因,這三種值互斥 — 一個文件只能有這三種值之一。)

        因此首先必須用屏蔽字O_ACCMODE相與取得存取方式位,然后將結果與這三種值相比較。      

   F_SETFL    設置給arg描述符狀態標志,可以更改的幾個標志是:O_APPEND,O_NONBLOCK,O_SYNC 和 O_ASYNC。而fcntl的文件狀態標志總共有7個:

        O_RDONLY , O_WRONLY , O_RDWR , O_APPEND , O_NONBLOCK , O_SYNC和O_ASYNC

二、非阻塞socket

  1.三次握手同時做其他的處理。connect要花一個往返時間完成,從幾毫秒的局域網到幾百毫秒或幾秒的廣域網。這段時間可能有一些其他的處理要執行,比如數據准備,預處理等。
  2.用這種技術建立多個連接。這在web瀏覽器中很普遍.
  3.由於程序用select等待連接完成,可以設置一個select等待時間限制,從而縮短connect超時時間。多數實現中,connect的超時時間在75秒到幾分鍾之間。有時程序希望在等待一定時間內結束,使用非阻塞connect可以防止阻塞75秒,在多線程網絡編程中,尤其必要。 例如有一個通過建立線程與其他主機進行socket通信的應用程序,如果建立的線程使用阻塞connect與遠程通信,當有幾百個線程並發的時候,由於網絡延遲而全部阻塞,阻塞的線程不會釋放系統的資源,同一時刻阻塞線程超過一定數量時候,系統就不再允許建立新的線程(每個進程由於進程空間的原因能產生的線程有限),如果使用非阻塞的connect,連接失敗使用select等待很短時間,如果還沒有連接后,線程立刻結束釋放資源,防止大量線程阻塞而使程序崩潰。



  目前connect非阻塞編程的普遍思路是:
  在一個TCP套接口設置為非阻塞后,調用connect,connect會在系統提供的errno變量中返回一個EINRPOCESS錯誤,此時TCP的三路握手繼續進行。之后可以用select函數檢查這個連接是否建立成功

 


免責聲明!

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



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