當前位置:編程學習大全網 - 編程語言 - C++ socket非阻塞模式

C++ socket非阻塞模式

壹、前言

初期學習socket的時候,為了方便理解,使用默認的阻塞模式比較多。而實際做項目時,我們必須考慮程序的並發性,非阻塞模式在其中擔任著很重要的角色,是必會的點之壹。本文不對阻塞IO和非阻塞IO的概念做說明,不了解的請自行了解。下文代碼以linux平臺為例。

二、設置非阻塞模式

設置非阻塞模式,通過fcntl方法設置,為了保存socket其他設置,壹般選擇先獲取 status flags, 並在其基礎上設置O_NONBLOCK屬性, 代碼如下:

fcntl失敗返回值為-1, 同時errno會被設置成對應的錯誤碼。(errno在此不做說明,不了解的自行了解。) 考慮失敗的情況,個人註意到網上有些例子(包括ss-libev項目)在 F_GETFL 失敗後,給了flags默認值,代碼如下:

經過測試,默認情況下,flags得到的值為2,也就是O_RDWR 讀寫, 而 0 對應的相關宏為O_RDONLY只讀,明顯不合理。個人感覺,對於壹個正常的socket來說,F_GETFL 出錯的機會不大吧, 至少我是沒遇到過。如果實在出錯了,還是建議走錯誤流程而不是給個默認值。

三、 非阻塞server

server端通常在accept後,我們為客戶端連接的fd設置為非阻塞。設置O_NONBLOCK後,recv和send發生了變化。默認阻塞模式下,recv在沒有數據可以接收(對方未發數據,或者緩沖區的數據已讀完對方沒有繼續發)情況下,recv會阻塞等待,直到下次有數據發送過來。而非阻塞模式下,recv在沒有數據可以接收的時候, recv會直接返回-1, 同時errno會被設置為EAGAIN/EWOULDBLOCK 。同理,非阻塞send也會在對方緩沖區滿的情況下直接返回-1並設置errno, 而不是阻塞等待。 非阻塞模式下server代碼大致如下:

四、非阻塞client

client除了在send/recv, 還可以在connect前設置非阻塞模式,這樣在connect時候可以直接返回。

client 非阻塞connect的時候,如果返回0表示連接成功,如果返回-1, 則需要判斷errno 是否為EINPROGRESS,EINPROGRESS表示非阻塞連接不能立刻獲取connect結果,後面可使用select/poll/epoll等對socket 可寫性進行判斷,如果socket已可寫,使用 getsockopt(iSocket, SOL_SOCKET, SO_ERROR ,&err, &len)進行判斷。。。好像挺麻煩是不是,但是我還是建議在大部分項目中connect前設置非阻塞(小工具之類的就無所謂了,項目中壹定要保證效率)。如果使用阻塞模式,有可能的問題:

下面是個非阻塞connect的部分代碼, 使用select, 至於poll/epoll請自行搜索代碼,跟非阻塞邏輯無關:

  • 上一篇:貼心機器人(寫作文)三年級
  • 下一篇:UG4.0怎麽在WIN7系統下安裝,我的是旗艦版的系統,最好能有視頻,謝謝
  • copyright 2024編程學習大全網