1. 程式人生 > >socket超時處理機制

socket超時處理機制

 在網路通訊中,socket處於阻塞模式執行時,其存在著超時處理。以下總結下在那些阻塞函式的處理方法。

這裡摘抄一段描述阻塞函式的描述,非常到位。

所謂阻塞函式,是指其完成指定的任務之前不允許程式呼叫另一個函式,在Windows下還會阻塞本執行緒訊息的傳送。

所謂非阻塞函式,是指操作啟動之後,如果可以立即得到結果就返回結果,否則返回表示結果需要等待的錯誤資訊,不等待任務完成函式就返回。

首先,非同步函式是非阻塞函式;

其次,獲取遠地資訊的資料庫函式是阻塞函式(因此,WinSock提供了其非同步版本);

在Berkeley socket函式部分中,不涉及網路I/O、本地端工作的函式是非阻塞函式;

在Berkeley socket函式部分中,網路I/O的函式是可阻塞函式,也就是它們可以阻塞執行,也可以不阻塞執行。這些函式都使用了一個socket,如果它們使用的socket是阻塞的,則這些函式是阻塞函式;如果它們使用的socket是非阻塞的,則這些函式是非阻塞函式

    其實說明阻塞還是非阻塞也是我們可以設定相關。這裡主要講解下處於阻塞模式下的超時處理。

1.在我們直接呼叫socket建立時,如果不進行特意宣告的話,建立的socket都是阻塞的。這樣當我們呼叫accept,recv時,將有可能“block”,如果想設定為非阻塞,則方法有呼叫fcntl,select,WSAAsynSelect 來改變socket的阻塞

hsocket = socket(AF_INET, SOCK_STREAM, 0)

fcntl(hsocket, F_SETFL, 0_NONBLOCK);

 注意:

    其中fcntl是Unix系統環境中使用的,使用ioctl()函式和fcntl()函式實現對套接字的控制,而在Windows系統中則應使用ioctlsocket()函式。

 Ioctl和fcntl的區別是:

  ioctl   -   control   device   
  ioctl()   performs   a   variety   of   control   functions     on     devices   
            and   STREAMS.     For   non-STREAMS   files,   the   functions   performed   
            by   this   call   are   device-specific   control   functions.     request   
            and     an   optional   third   argument   with   varying   type   are   passed   
            to   the   file   designated   by   fildes   and   are   interpreted   by     the   
            device   driver.   
    The   fcntl()   function   provides   control   of   open   file   descriptors.   It   is   similar   to   ioctl().

   ( 這些帶著unix的體味的函式,看著就頭大。這個我是摘自某個文件,設定超時應該採用ioctlsocket。)

1.呼叫MFC的CAsyncSocket和CSocket類

  MFC提供了兩個類CAsyncSocket和CSocket來封裝WinSock API,

  CAsyncSocket在較低層次上封裝了WinSock API,預設情況下,使用該類建立的socket是非阻塞的socket,所有操作都會立即返回,如果沒有得到結果,返回WSAEWOULDBLOCK,表示是一個阻塞操作。

  CSocket建立在CAsyncSocket的基礎上,是CAsyncSocket的派生類。也就是預設情況下使用該類建立的socket是非阻塞的socket,但是CSocket的網路I/O是阻塞的,它在完成任務之後才返回。CSocket的阻塞不是建立在“阻塞”socket的基礎上,而是在“非阻塞”socket上實現的阻塞操作,在阻塞期間,CSocket實現了本執行緒的訊息迴圈,因此,雖然是阻塞操作,但是並不影響訊息迴圈,即使用者仍然可以和程式互動。(即程式不會freeze)。

  其中設定超時函式如下:

CAsyncSocket::SetSockOpt(   int   nOptionName,   const   void*   lpOptionValue,   int   nOptionLen,   int   nLevel   =   SOL_SOCKET   );   
  nOptionName用SO_SNDTIMEO   or   SO_RCVTIMEO。  

2.採用select處理超時

int select(int nfds, fd_set FAR* readfds, fd_set FAR* writefds,fd_set FAR*exceptfds, const struct timeval FAR* timeout)

其中在windows中,其nfds可以可以設定為0,沒有實際意義。

fd_set  fdR;
struct  timeval timeout = ..; //設定超時時間
...
for(;;) {
        FD_ZERO(&fdR);
        FD_SET(sockfd, &fdR);
        switch (select(sockfd + 1, &fdR, NULL, &timeout)) {
                case -1:
                    //錯誤,需要關閉埠。。。
                case 0:

                   //  timeout 處理

                default:
                        if (FD_ISSET(sockfd)) { 

                            //或讀寫操作或Accept()操作,按你設定處理。
                        }
        }
}

注意的是:

     由於Windows Sockets 某些函式在介面上雖然與Unix Sockets一致,但是它們的內部實現卻不一樣,例如,在函式select()的引數中,Unix Sockets實現套接字集合使用的是位掩碼,但在Windows Sockets中卻是使用一個SOCKET的陣列。雖然套接字的集合仍由fd_set型別表示,但在Unix Sockets 原始檔中直接修改fd_set結構的程式碼在Windows Sockets環境下將不能正常工作。故fd_set在微軟中則採用FD_XXX巨集處理。

3.採用WSAsyncSelect() 

   這個是訊息事件模式來處理的,通過其中引數控制代碼返回一個訊息,在自定義訊息中處理。

4.採用setsockopt設定超時

int PASCAL FAR setsockopt( SOCKET s, int level, int optname,
const char FAR* optval, int optlen);

s:標識一個套介面的描述字。
level:選項定義的層次;目前僅支援SOL_SOCKET和IPPROTO_TCP層次。
optname:需設定的選項。
optval:指標,指向存放選項值的緩衝區。
optlen:optval緩衝區的長度。

     setsockopt()函式用於任意型別、任意狀態套介面的設定選項值。儘管在不同協議層上存在選項,但本函式僅定義了最高的“套介面”層次上的選項。選項影響套介面的操作,諸如加急資料是否在普通資料流中接收,廣播資料是否可以從套介面傳送等等。
  有兩種套介面的選項:

      一種是布林型選項,允許或禁止一種特性;

      一種是整形或結構選項。允許一個布林型選項,則將optval指向非零整形數;禁止一個選項optval指向一個等於零的整形數。

        對於布林型選項,optlen應等於sizeof(int);對其他選項,optval指向包含所需選項的整形數或結構,而optlen則為整形數或結構的長度。

      SO_LINGER選項用於控制下述情況的行動:套介面上有排隊的待發送資料,且closesocket()呼叫已執行。參見closesocket()函式中關於SO_LINGER選項對closesocket()語義的影響。應用程式通過建立一個linger結構來設定相應的操作特性。

      這個setsockopt的水也太深了,對於一般運用大致運用就行,主要是其中引數太多,只需要瞭解幾個就可以了,至於想了解更多,則讀msdn吧,以及相關的文件吧,不過感覺這些東西純粹就是個技術指標細節,不需要動腦筋卻需要了解的一個方面,說白了是這些都是技術活而不是腦力活。

常見的命令:

//確定套接字自動讀入的資料量

#define FIONREAD _IOR(''''f'''', 127, u_long) /* get # bytes to read */

//允許或禁止套接字的非阻塞模式,允許為非0,禁止為0

#define FIONBIO _IOW(''''f'''', 126, u_long) /* set/clear non-blocking i/o */

//確定是否所有帶外資料都已被讀入

#define SIOCATMARK _IOR(''''s'''', 7, u_long) /* at oob mark? */

設定接受超時

相關推薦

socket超時處理機制

 在網路通訊中,socket處於阻塞模式執行時,其存在著超時處理。以下總結下在那些阻塞函式的處理方法。這裡摘抄一段描述阻塞函式的描述,非常到位。所謂阻塞函式,是指其完成指定的任務之前不允許程式呼叫另一個函式,在Windows下還會阻塞本執行緒訊息的傳送。所謂非阻塞函式,是指操

一種極簡的非同步超時處理機制設計與實現(C#版)

1.引言 當執行某些動作之後,會期待反饋。最終要麼是得到了結果,要麼就是超時了。當超時發生時,可能是期望得到通知,或是希望能自動重試,等等。於是設計了一種通用的非同步超時的處理機制,以期通過簡潔易理解的方式完成超時的處理過程。 2.對外介面設計 從使用的角度,呼叫方期望的是“指定超時時長,時間到自動執行指定過

Nginx 超時事件的處理機制

本文基於Nginx 0.8.55原始碼,並基於epoll機制分析 對於nginx而言,事件機制的處理無非就是幾個部分: 網路IO事件的處理 檔案IO事件的處理 定時器事件的處理 (當然還有許多其他的不過我現在並不是很關心。。) 我在讀Nginx定時器事件相關的程式碼時看到了很

[轉]關於VC++ MFC中的空閑Idle處理機制

normal 函數 系統 true check track cor idle 行處理 關鍵詞:   先根據空閑標誌以及消息隊列是否為空這兩個條件判斷當前線程是否處於空閑狀態(這個“空閑”的含義同操作系統的含義不同,是MFC自己所謂的“空閑”),如果是,就調用CW

PHP 錯誤處理機制

系統 提示信息 not 註釋 運行 系統錯誤 輸出 ice 攻擊 在日常的項目開發過程中,總是會出現一些我們意想不到的異常錯誤,如果我們對此沒有進行相對完善的處理,那麽程序看上去也很不專業,也很可能就會成為別人攻擊系統的有效信息;有些錯誤異常會終止腳本執行,這個

Storm消息可靠處理機制

字符串 cti put 計算 size pan pen bolt blog 在很多應用場景中,分布式系統的可靠性保障尤其重要。比如電商平臺中,客戶的購買請求需要可靠處理,不能因為節點故障等原因丟失請求;比如告警系統中,產生的核心告警必須及時完整的知會監控人員,不能因為網絡故

從零開始理解JAVA事件處理機制(2)

extend nds 接下來 htm ref param 簡單 tostring ansi 第一節中的示例過於簡單《從零開始理解JAVA事件處理機制(1)》,簡單到讓大家覺得這樣的代碼簡直毫無用處。但是沒辦法,我們要繼續寫這毫無用處的代碼,然後引出下一階段真正有益的代碼。

HttpURLConnection超時處理

for back aik aqi neo can pac yun jcp Python%E5%85%A8%E6%A0%88%E5%BC%80%E5%8F%91%E4%B9%8B9%E3%80%81%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E3

Linux程序設計學習筆記——異步信號處理機制

基本概念 erro 驗證 添加 uid 函數 count ubun generate 轉載請註明出處: http://blog.csdn.net/suool/article/details/38453333 Linux常見信號與處理 基本概念 Linux的信號是一

事件處理機制--瀏覽器流程處理分析

style chan 一件事 cli con open() -h response xhr 事件處理機制--瀏覽器流程處理分析 js的運行是單線程的,單線程即一個時間只能做一件事。瀏覽器的運行是多線程的。 如下三種情況會進入事件隊列(任務隊列)中,但不立即執行:   1.定

關於表單form元素中onsubmit事件處理機制的認識

讓我 clas 教程 是否 它的 默認方法 對象實例 action 事件處理機制   博主目前處於Js學習的初期,遇到了很多問題,比如今天的關於表單form元素中onsubmit事件問題,根據教程所述,onsubmit事件是在表單提交的時候觸發的,但是我看到教程上的onsu

Java中的內存處理機制和final、static、final static總結

stat 入口 引用類型 堆棧 class a 如果 虛擬 不同 bsp Java中的內存處理機制和final、static、final static總結 裝載自:http://blog.csdn.net/wqthaha/article/details/209235

C語言中的異常處理機制

軟件測試 如何實現 char* oar 朋友 核心 初始化 flag out #define try if(!setjmp(Jump_Buffer)) 返回try現場後重新執行判斷,所以有兩次執行。 http://blog.csdn.net/tian_dao_chou_q

Android---Handler消息處理機制

bsp cte string ack 消息處理 libc from 原因 entity 搞Android的人都知道。android是不同意你在子線程中更新UI操作的。這主要出於線程安全方面的考慮。通常的做法是在主線程中創建一個Handler對象,在子線

七、異常處理——2-異常處理機制

left ron text pan 異常處理機制 異常類 捕獲異常 p s 捕獲 2-異常處理機制 1.使用try...catch捕獲異常 2.異常類的繼承體系七、異常處理——2-異常處理機制

MFC消息處理機制

映射 處理 add 實現 gui 實現類 res msdn 方法 1、如果要在一個代表窗口的類(代表窗口的類,都派生於CWnd)中處理消息,那麽:   1.1、如果處理的Windows消息是WM_XXX,那麽可以在MSDN中通過ON_WM_XXX來查找到相關說明。   1.

MFC宏消息處理機制的原理

creates clas poi basemap 保持 改變 all 機制 int 1.1、在MFC中處理消息的函數是固定的,如afx_msg int OnCreate(LPCREATESTRUCT);這是一個固定的,對應於ON_WM_CREAT()宏。如果改變了函數名,對

3.1_SpringBoot內部處理機制解析

ext tom list process eba 版本 代碼 http eric 前言 目前基於SpringBoot進行Web應用開發已經成為一個趨勢,Spring官網內部的很多入門Demo都是基於SpringBoot的,因此掌握SpringBoot成為當下基於Java的W

Qt ------ 事件處理機制

後處理 分發 異步 ant ont 事件循環 tar rpo 基類 簡介 在Qt中,事件被封裝成一個個對象,所有的事件均繼承自抽象類QEvent。Qt是以事件驅動UI工具集。Signals/Slots在多線程中的實現也是依賴於Qt的事件處理機制。在Qt中,事件被封裝成一個個

C#進階--WebApi異常處理機制

str with 分配 客戶 來看 stack 統一 releases 全局配置 其實對於C#異常處理大家都不陌生,但是對於在WeiApi上的異常處理實際上也和傳統異常處理區別不大,但是卻經過封裝可以讓異常更加友好,https://docs