在用ReadFile和WriteFile讀寫串行口時,需要考慮超時問題。如果在指定的時間內沒有讀出或寫入指定數量的字符,那麼ReadFile或WriteFile的操作就會結束。要查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設置超時。有兩種超時:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大時延,總超時是指讀寫操作總共花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。
COMMTIMEOUTS 結構體被用在SetCommTimeouts和GetCommTimeouts 函數中,以便設置和查詢通訊設備的超時參數。這個參數決定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,則在寫操作時忽略總超時數。
提示:用戶設置通訊超時後,如沒有出錯,串口已經被打開。
- ReadIntervalTimeout
- 在通訊過程中接收兩個字符之間的最長超時時間,按毫秒計算。在ReadFile操作,當接收到第一個字符時,開始一個計時週期。如果接收任意兩個字符之間的時隔超過本限制,ReadFile操作將完成並返回任何已緩衝的數據。0代表本參數未設置。
如果設置爲MAXDWORD, 並且ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier成員爲0,代表讀取操作立即返回那些已接收的數據,即使沒有收到任何字符。(兩個字符之間的接收間隔)
- ReadTotalTimeoutMultiplier
- 乘數用於計算讀取操作的總超時時間,按毫秒計算。對於每個讀取操作,這個值將乘以要讀取的字節數。(讀取單個字符的最大超時)
- ReadTotalTimeoutConstant
- 一個用於計算對於讀取操作的總超時週期的常數,按毫秒計算。對每次讀取操作,實際總超時時間爲ReadTotalTimeoutMultiplier 成員與請求的字節數年的乘積加此值。
ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant成員爲0代表總讀取總超時時間無效(讀取所有字節的時間爲ReadTotalTimeoutMultiplier*BytesToRead+ReadTotalTimeoutConstant)。
- WriteTotalTimeoutMultiplier
- 乘數用來計算寫操作的總超時週期,按毫秒計算。對每個寫操作,這個值將乘以要寫入的字節數。(寫單個字符的最大超時)
- WriteTotalTimeoutConstant
- 一個用於計算寫入操作的總超時週期的常數,按毫秒計算。對於每一次寫入操作,實際總超時時間爲WriteTotalTimeoutMultiplier 成員與要寫入字節的乘積再加此值.
WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant成員爲0代表總寫入時間無效(寫入所有字節的時間爲WriteTotalTimeoutMultiplier*BytesToWrite+WriteTotalTimeoutConstant)。
備註
如果一個應用程序設置ReadIntervalTimeout和ReadTotalTimeoutMultiplier爲 MAXDWORD並且設置ReadTotalTimeoutConstant 爲一個大於零且小於MAXDWORD的值, 在調用ReadFile時將會發生如下現象:
- 如果在輸入緩衝區中有任何字符,ReadFile 立即返回緩衝區中的內容。
- 如果在緩衝區中沒有任何字符,ReadFile 將等待接收到一個字符並立即返回.
- 如果在ReadTotalTimeoutConstant指定的時間值內無任何字節返回,ReadFile超時.