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函數檢查這個連接是否建立成功
總結
以上是生活随笔為你收集整理的Socket,非阻塞,fcntl的全部內容,希望文章能夠幫你解決所遇到的問題。