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超时.



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