l转载:计算机传真中串行通信的研究与实现

计算机传真中串行通信的研究与实现

彭爱国 李建华

  在现代社会中,传真传输已成为远程通信领域的主要工具之一,而随着计算机通信及网络技术的发展,传真传输不再只限于专用的传真机,事实上,利用计算机和传真调制解调器实现传真功能已经得到了越来越广泛的应用。
  设计传真软件的最基本也是最关键的一部分就是串行通信,串行通信的正确与否直接关系到传真是否能正确接收与发送。

1 计算机传真的工作原理
  计算机传真的基本思想是在串行通信的基础上,利用计算机、Fax Modem和电话,根据T.30和T.4两个协议来模拟传真机,实现所有传真功能。其中T.30为传真通信协议,它规定了一次传真会话的过程:首先,两个调制解调器将建立一个在PSTN上的电话连接;然后,通过在一个300bps(可选为2400bps)半双工同步连接上交换HDLC信息帧,这两个调制解调器将实现一个带差错控制的T.30"会话";第三,在会话的起始部分,两个调制解调器赞同可接受的参数,这时,发送方将发出一个高速载波脉冲,以验证电话线路的质量,然后,两个调制解调器都将切换到一个高速状态,从而以半双工方式一次一页传输图象;第四,在每页的结束处,调制解调器回到一个较低速(通常为300bps)会话协议,以协商下一页(如有必要,也可协商重发上页);最后,当无更多页发送时,调制解调器断连。T.4为传真图象协议,它规定了T.30中阶段C中数据的尺寸和编码规范,如传真文件的尺寸、扫描仪/打印机的分辨率、为压缩数据而采用的编码算法、带行同步序列,即行终码EOL、阶段C的带内转义序列,即返回控制信号RTC,以及适应低速输出设备所需要的填充技术等。

2 传真与数据传输的差别
  (1) 传真站之间传送的所有数据均为图象数据,在交互式对话过程中传送于主系统和远地站之间。
  (2) 传输单元的不同。在XModem或YModem协议中,包是传输单元,而在传真传输中,使用的术语是帧或HDLC(高级数据链路控制)帧。传真数据的最小单元是页。
  (3) 数据通信一般是面向字节进行传输的,而传真传输是面向比特流的,一页上描述数据的信息是一系列可变长的位串。从计算机的角度来看,这些位串是被当作一系列字节来接收和发送的,位串的每一位在接收时都要被解释直到它在T.4描述传真数据的表中遇到某一匹配字串时为止。

3 传真中串行通信的几种方法
  利用Fax Modem 和计算机模拟传真机进行传真的接收与发送,是在串行通信的基础上加上对Modem的操作,根据T.30和T.4协议来实现的。Windows中有以下几种常用的串行通信方法:
  (1) 查询法
  Windows 3.1、Win95/98环境下的查询通信方式的基本编程思想基本一致,采用CPU定时查询,检测是否接收到新的数据或数据是否发送完毕,其基本的程序结构如图1。

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 

1查询方式实现传真传输框图

  (2) 利用通信控件
  在Windows3.1下,VB3.0提供了VBX控件MSCOMM.VBX,VC1.0/1.5的类库提供了CVBControl类,使得应用程序可以方便地处理VBX控件。 在Win95/98下,从VC2.0起,舍弃了VBX控件,逐步由OLE控件和ActiveX控件取而代之,与通信VBX控件MSCOMM.VBX相对应通信OLE控件为MSCOMM16.OCX(16位)和MSCOMM32.OCX(32位)。
  (3) 线程事件驱动方式
  在Windows 3.1下,当设置通信事件后,每次指定的通信事件发生时,通信驱动程序将自动向应用程序发送通信通知消息WM_COMMNOTIFY,它指示了一个窗口的发送和接收缓冲区的状态。 Win95/98通信机制与Windows3.1有很大差异,不再有WM_COMMNOTIFY通知消息,为了实现中断通信,Win95/98提供了线程处理方法,使得程序员能够完全控制程序片断的执行,进行实时收发数据。
  用方法1实现传真通信十分简单,但耗时、效率不高,故此方法不能做到实时收发数据,容易引起数据的丢失。方法2使用通信控件,大大简化了通信编程,可通过其提供的通信事件来进行实时收发数据,并提供了大量的属性和方法,用于普通的串行通信不失为一种较好的方法,但该方法对扩展ASCII字符和ASCII 0(也就是该字符的ASCII值为0)的传送会显得力不从心,不能正确完成数据传输,而在传真应用程序中,传真中的传输单元帧中的许多标志字有的就是扩展ASCII,传真数据是图象数据经过编码之后进行传送的,是一种面向比特流的数据,因而在传送的数据中,是会经常碰到扩展ASCII字符和ASCII 0的,因而这种方法也不适合用于串行数据的传输。方法3克服了上述几种方法的不足,具有高效率、准确性好、能满足传真传输的基本要求。

4 线程事件方式的实现
  在Win95/98环境下,线程是唯一执行单位,是Win32为程序分配CPU时间的基本实体。每个正在运行的应用程序构成一个进程,每个进程包括一个或多个线程,各线程协同完成指定操作,应用程序中的进程是作为单独的线程开始它的生命期的。MFC将执行的线程封装在CWinThread类中,包括创建、管理和删除线程的一系列成员变量和成员函数。
  线程通信方式的主要思路是单独创建一个通信线程,它主要实现对通信事件的监视,如检测重叠I/O操作是否完成以及是否接收到新的数据等。
  为了便于维护,把串口通信设计成一个类CCommCtrl,它实现了诸如打开串口、配置串口、向串口发送数据、关闭串口等方法,同时还完成通信事件的监视。
  当进程启动之后,首先创建主线程,然后创建通信线程,并将其挂起,再调用类CCommCtrl中的成员函数完成串口的初始化、创建同步对象、设置事件掩模等,然后在合适的时候继续执行通信线程,由其完成通信事件的监视。每当有通信事件时,就向主线程发送自定义消息。图2是主要流程。

2线程通信实现传真输流程图

  (1) 创建线程 m_commctrl = (CCommCtrl*)AfxBeginThread (RUNTIME_CLASS(CCommCtrl),THREAD_PRIORITY_NORMAL,0,REATE_SUSPENDED);
  其中m_commctrl为CCommCtrl对象,CCommCtrl为CWinThread派生对象的RUNTIME_CLASS,THREAD_PRIORITY_NORMAL为线程的优先级,CREATE_SUSPENDED表示线程的创建形式为挂起。
  (2) 打开串口和配置串口
  1)用CreateFile函数打开串口资源。CreateFile的函数原型为:
  HANDLE CreateFile(LPCTSTR lpFileName, //指向串名的指针,如"COM2";DWORD dwDesiredAccess, //访问模式,可以有是读或写或都是;DWORD dwShareMode, //共享模式,对于通信资源,只能为0;LPSECURITY_ATTRIBUTES lpSecurityAttibutes, //指向安全模式描述符的指针;DWORD dwCreationDistribution, //对于通信资源,它必须为OPEN_EXISTING;DWORD dwFlagsAndAttributes, //指定属性和标志;HANDLE hTemplateFile //模板文件句柄,对于通信资源,必须为0)
  如果函数调用成功,则返回指定通信资源的一个打开的句柄;否则返回INVALID_HANDLE_VALUE。
  2)用GetCommState函数获取串行资源的当前配置,再使用SetCommState函数重新配置串行资源各参数。然后再用SetupComm函数来设置缓冲区大小。
  3)当以上都完成后,就可以用ReadFile和WriteFile来进行串口数据的读写了。
  (3)通信事件
  1)设置事件掩模
  通过SetCommMask函数建立事件掩模来监视指定通信资源上的事件,其原型为:
  BOOL SetCommMask (HANDLE hFile, //通信设备句柄,由CreateFile返回;DWORD dwEvtMask //被监视的事件)
  2)监视通信事件
  在指定被监视的事件掩模之后,进程使用WaitCommEvent函数等待其中一个事件发生。WaitCommEvent的原型为:
  BOOL WaitCommEvent ( HANDLE hFile, //通信设备句柄,由CreateFile返回;LPDWORD lpEvtMask, //指向存放当前发生事件的变量;LPOVERLAPPED lpOverlapped // 指向一个LPOVERLAPPED结构)
  (4)重叠I/O操作
  重叠操作使得线程从费时的I/O操作中解脱出来,让I/O操作在后台执行,而线程可以自由执行其它任务。当使用重叠操作时,I/O操作不管是否完成都立即返回。
  如果要想通信设备能执行重叠操作,必须在使用CreateFile打开通信设备时, dwFlagsAndAttributes参数必须指定为FILE_FLAG_OVERLAPPED与其它标志的组合。同时要按重叠操作执行的函数,其参数中必须指定指向OVERLAPPED结构的指针,最后,OVERLAPPED结构必须包含手工重置事件对象。

5 结束语
  利用线程事件方式来实现串行通信,能够很好地解决传真的实时接收和发送数据,同时也能保证扩展ASCII字符和ASCII 0的正确传输,这种方法不仅可以用在传真系统中;也可用在那些需要实时传输数据的串行通信场合,如监控系统;也可用在文件传输,尤其是所传输的文件是图象文件等其它二进制文件。

作者单位:长沙铁道学院信息技术研究中心,长沙410075

参考文献
1 [日]通信协议手册编委会编.最新网络通信协议手册.北京:电子工 业出版社,1999
2 [美]Galtan P W.精通串行通信.北京:电子工业出版社,1994
3 [美]Holmes M,Flanders B.C++通信实用程序.北京: 电子工业出 版社,1995
4 [美]Leinedker R C.Windows 98 编程实用大全.北京:中国水利水 电出版社,1999

 

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