COMMTIMEOUTS詳解(轉)

 

 在用ReadFile和WriteFile讀寫串行口時,需要考慮超時問題。如果在指定的時間內沒有讀出或寫入指定數量的字符,那麼ReadFile或WriteFile的操作就會結束。要查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設置超時。有兩種超時:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大時延,總超時是指讀寫操作總共花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。


COMMTIMEOUTS 結構體被用在SetCommTimeoutsGetCommTimeouts 函數中,以便設置和查詢通訊設備的超時參數。這個參數決定ReadFile,WriteFile,ReadFileEx, 和WriteFileEx 操作設備的行爲。

 

typedef struct _COMMTIMEOUTS {
  DWORD ReadIntervalTimeout;
  DWORD ReadTotalTimeoutMultiplier;
  DWORD ReadTotalTimeoutConstant;
  DWORD WriteTotalTimeoutMultiplier;
  DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS, *LPCOMMTIMEOUTS;

成員

用COMMTIMEOUTS結構可以規定讀/寫操作的超時,該結構的定義爲:  

typedef struct _COMMTIMEOUTS {

  DWORD ReadIntervalTimeout; //讀間隔超時。 接收時,兩字符間最大的時延。

  DWORD ReadTotalTimeoutMultiplier; //讀時間係數。讀取每字節的超時。

  DWORD ReadTotalTimeoutConstant; //讀時間常量。讀串口數據的固定超時。
             //
總超時  =  ReadTotalTimeoutMultiplier  *  字節數  +  ReadTotalTimeoutConstant  
  DWORD WriteTotalTimeoutMultiplier; //寫時間係數。寫每字節的超時。

  DWORD WriteTotalTimeoutConstant; //寫時間常量。寫串口數據的固定超時。
            
// 總超時  =    WriteTotalTimeoutMultiplier *  字節數   +   WriteTotalTimeoutConstant 
  }COMMTIMEOUTS,*LPCOMMTIMEOUTS;
 
COMMTIMEOUTS  comTimeOut;   //  COMMTIMEOUTS對象 
SetCommTimeouts(handlePort_,&comTimeOut);  //  將超時參數寫入設備控制

ReadIntervalTimeout:

指定通訊線上兩個字符到達的最大時延,以毫秒爲單位。在ReadFile操作期間,時間週期從第一個字符接收到算起。如果收到的兩個字符之間的間隔超過該值,ReadFile操作完畢並返回所有緩衝數據。如果ReadIntervalTimeout爲0,則該值不起作用。

如果值爲MAXDWORD,  並且ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier兩個值都爲0,  則指定讀操作攜帶已經收到的字符立即返回,即使沒有收到任何字符。

ReadTotalTimeoutMultiplier:

指定以毫秒爲單位的累積值。用於計算讀操作時的超時總數。對於每次讀操作,該值與所要讀的字節數相乘。

ReadTotalTimeoutConstant : 

指定以毫秒爲單位的常數。用於計算讀操作時的超時總數。對於每次讀操作,ReadTotalTimeoutMultiplier與所要讀的字節數相乘後與該值相加。

如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都爲0,則在讀操作時忽略總超時數。

WriteTotalTimeoutMultiplier:  

指定以毫秒爲單位的累積值。用於計算寫操作時的超時總數。對於每次寫操作,該值與所要寫的字節數相乘。

WriteTotalTimeoutConstant:

指定以毫秒爲單位的常數。用於計算寫操作時的超時總數。對於每次寫操作,  WriteTotalTimeoutMultiplier與所要寫的字節數相乘後與該值相加。

如果  WriteTotalTimeoutMultiplier  和  WriteTotalTimeoutConstant都爲0,則在寫操作時忽略總超時數。

提示:用戶設置通訊超時後,如沒有出錯,串口已經被打開。

  COMMTIMEOUTS結構的成員都以毫秒爲單位。  總超時的計算公式是:  總超時=時間係數×要求讀/寫的字符數 + 時間常量  例如,如果要讀入10個字符,那麼讀操作的總超時的計算公式爲:  讀總超時=ReadTotalTimeoutMultiplier×10 +ReadTotalTimeoutConstant  可以看出,間隔超時和總超時的設置是不相關的,這可以方便通信程序靈活地設置各種超時。如果所有寫超時參數均爲0,那麼就不使用寫超時。如果ReadIntervalTimeout爲0,那麼就不使用讀間隔超時,如果  ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都爲0,則不使用讀總超時。如果讀間隔超時被設置成MAXDWORD並且兩個讀總超時爲0,那麼在讀一次輸入緩衝區中的內容後讀操作就立即完成,而不管是否讀入了要求的字符。在用重疊方式讀寫串行口時,雖然ReadFile和WriteFile在完成操作以前就可能返回,但超時仍然是起作用的。在這種情況下,超時規定的是操作的完成時間,而不是ReadFile和WriteFile的返回時間。



ReadIntervalTimeout
在通訊過程中接收兩個字符之間的最長超時時間,按毫秒計算。在ReadFile操作,當接收到第一個字符時,開始一個計時週期。如果接收任意兩個字符之間的時隔超過本限制,ReadFile操作將完成並返回任何已緩衝的數據。0代表本參數未設置。

如果設置爲MAXDWORD, 並且ReadTotalTimeoutConstantReadTotalTimeoutMultiplier成員爲0,代表讀取操作立即返回那些已接收的數據,即使沒有收到任何字符。(兩個字符之間的接收間隔)

ReadTotalTimeoutMultiplier
乘數用於計算讀取操作的總超時時間,按毫秒計算。對於每個讀取操作,這個值將乘以要讀取的字節數。(讀取單個字符的最大超時)
ReadTotalTimeoutConstant
一個用於計算對於讀取操作的總超時週期的常數,按毫秒計算。對每次讀取操作,實際總超時時間爲ReadTotalTimeoutMultiplier 成員與請求的字節數年的乘積加此值。

ReadTotalTimeoutMultiplierReadTotalTimeoutConstant成員爲0代表總讀取總超時時間無效(讀取所有字節的時間爲ReadTotalTimeoutMultiplier*BytesToRead+ReadTotalTimeoutConstant)。

WriteTotalTimeoutMultiplier
乘數用來計算寫操作的總超時週期,按毫秒計算。對每個寫操作,這個值將乘以要寫入的字節數。(寫單個字符的最大超時)
WriteTotalTimeoutConstant
一個用於計算寫入操作的總超時週期的常數,按毫秒計算。對於每一次寫入操作,實際總超時時間爲WriteTotalTimeoutMultiplier 成員與要寫入字節的乘積再加此值.

WriteTotalTimeoutMultiplierWriteTotalTimeoutConstant成員爲0代表總寫入時間無效(寫入所有字節的時間爲WriteTotalTimeoutMultiplier*BytesToWrite+WriteTotalTimeoutConstant)

備註

如果一個應用程序設置ReadIntervalTimeoutReadTotalTimeoutMultiplier爲 MAXDWORD並且設置ReadTotalTimeoutConstant 爲一個大於零且小於MAXDWORD的值, 在調用ReadFile時將會發生如下現象:

 

 

  • 如果在輸入緩衝區中有任何字符,ReadFile 立即返回緩衝區中的內容。
  • 如果在緩衝區中沒有任何字符,ReadFile 將等待接收到一個字符並立即返回.
  • 如果在ReadTotalTimeoutConstant指定的時間值內無任何字節返回,ReadFile超時.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章