windows下的6種IO模型

來源:互聯網
上載者:User

標籤:好的   tab   win   問題   迴圈   blocking   上下   width   str   

阻塞模型
int recv(
SOCKET s,
char* buf,
int len,
int flags
);
int send(
SOCKET s,
const char* buf,
int len,
int flags
);

這種方式最為大家熟悉,Socket預設的就是阻塞模式。

在recv的時候,Socket會阻塞在那裡,直到串連上有資料可讀,把資料讀到buffer裡後recv函數才會返回,不然就會一直阻塞在那裡。

如果在主線程中被阻塞,而資料遲遲沒有過來,那麼程式就會被鎖死。這樣的問題可以用多線程解決,但是在有多個通訊端串連的情況下,這不是一個好的選擇,擴充性很差,而且也容易有鎖的問題。線程過多,也導致環境切換過於頻繁,導致系統變慢,而且大部分線程是處於非使用中的話,這就大大浪費了系統的資源。

設定為非阻塞:
int ioctlsocket(
IN SOCKET s,
IN long cmd,
IN OUT u_long FAR * argp
);
#define FIONBIO /* set/clear non-blocking i/o */

調用ioctlsocket函數設定FIONBIO為1就轉為非阻塞模式。

當recv和send函數沒有準備好資料時,函數不會阻塞,立即返回錯誤值,用GetLastError返回的錯誤碼為WSAEWOULDBLOCK,中文解釋為“無法立即完成一個非阻擋性通訊端的操作”。

當然,這裡你可以用非阻塞類比阻塞模式,就是用while迴圈不停調用recv,直到recv返回成功為止。這樣的效率也不高,但好處在於你能在沒接收到資料時,有空進行其他動作,或者直接Sleep。

把通訊端設定為非阻塞模式,即告訴系統:在調用Windows socket API時,不讓主調線程睡眠,而讓函數立即返回。比如在調用recv函數時,即使此時接受緩衝區沒有資料,也不會導致線程在recv處等待,recv函數會立即返回。如果沒有調用成功函數會返回WSAEROULDBLOCK錯誤碼。為了接收到資料必須迴圈調用recv,這也是非阻塞與阻塞模式的主要區別。

 

unsigned long ul=1;    int ret;    s=socket(AF_INET,SOCK_STREAM,0);    ret=ioctlsocket(s,FIONBIO,(unsigned long *)&ul);//設定成非阻塞模式。    if(ret==SOCKET_ERROR)//設定失敗。    {    }  

 

  

 

windows下的6種IO模型

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.