深入Windows通信編程
一、Windows通信機制Windows與DOS編程的重要差別在于Windows程序是消息驅(qū)動和設備統(tǒng)一管理。體現(xiàn)在通信方面,DOS中的寄存器直接讀寫、BIOS調(diào)用和通信中斷程序等編程方法都不能或不宜采用。Windows通過通信驅(qū)動程序COMM.DRV與硬件接口,向程序員提供了多達17個標準函數(shù),功能強大,但也增加了理解和編程的難度。
Windows3.1通信函數(shù)主要有:
OpenComm
打開一通信設備
BuildCimmDCB將一設備定義字符串轉(zhuǎn)變?yōu)镈CB數(shù)據(jù)結(jié)構(gòu)
EnableCommNotification使能或禁止傳送WM_COMMNOTIFY消
息
SetCommState設置通信設備狀態(tài)
SetCommEventMask設置通信事件掩碼
ReadComm從通信設備讀字符
WriteComm向通信設備寫字符
FlushComm清除一發(fā)送或接收隊列
GetCommEventMask返回通信事件掩碼
GetCommState返回設備控制塊(DCB)
GetCommError恢復通信設備狀態(tài)
CloseComm關(guān)閉一通信設備
DCB數(shù)據(jù)結(jié)構(gòu)、其它通信函數(shù)及各函數(shù)的具體用法請參見有關(guān)資料。
一般Windows通信編程應包括兩部分:設備初始化及WM_COMMNOTIF
Y消息處理。
設備初始化典型流程如圖1。
圖1
WM_COMMNOTIFY消息處理典型流程如圖2。
圖2
對于大多數(shù)實際通信來說,可能只需要處理流程圖中的一部分。
設備初始化及WM_COMMNOTIFY消息處理兩部分密切相關(guān)。所有類型WM_COMMNOTIFY消息的傳送都是因為在初始化函數(shù)中進行了相應的設置。
換言之,可以根據(jù)通信的實際情況有選擇地設置,控制Windows向應用程序發(fā)送的WM_COMMNOTIFY消息的數(shù)量和類型,以期達到高效、可靠的通信。例如,對于固定長度消息型的通信可以在EnableCommNotification函數(shù)中設置cbWriteNotify和cbOutQueue參數(shù)為消息長度;對于以固定字符結(jié)尾的消息型通信可以在事件掩碼中包括EV_RXFLAG,將DCB數(shù)據(jù)結(jié)構(gòu)中的EvtChar變量置為結(jié)尾字符,然后調(diào)用SetCommState和SetCommEventMask函數(shù);對于遵循V.25bis之類協(xié)議的通信,由于用到了大量信號線來作握手信號,則事件掩碼中要包含EV_CTS、EV_DSR、EV_RSLD及EV_RING等;而對于文件傳送型的通信,則宜將OpenComm函數(shù)中的cbInQue和cbOutQue變量、EnablecCommNotification中的cbWriteNotify和cbOutQueue變量設置為較大值,以加快文件傳送速度。
二、Windows通信疑難探討
現(xiàn)將筆者在實際編程中遇到的疑難和解決辦法描述如下,希望對遇到類似問題的朋友有所啟發(fā)。
1.怎樣用Windows未提供的波特率通信?
Windows提供了由110bps至256000bps共十三種波特率,一般情況下已足夠使用。但在某種特定情況下,例如通信對方使用150bps、又無法要求對方改變波特率時,Windows通信就比較困難了。
首先想到的解決方法是直接調(diào)用BIOS中斷14H來設置波特率(DOS提供了150bps的波特率)。結(jié)果是Windows屏蔽了該中斷,嘗試失敗。
最后的是采用"蒙混過關(guān)"的辦法解決問題的:首先,以任一Windows支持的波特率(例如300bps)構(gòu)造通信參數(shù)字符串,調(diào)用BuildCommDCB產(chǎn)生DCB數(shù)據(jù)結(jié)構(gòu);然后調(diào)用SetCommState設置通信參數(shù);最后再調(diào)用自編函數(shù)直接修改串口通信寄存器的值。經(jīng)實驗,設置成功,且對Windows程序運行無任何不良影響。
2.接收數(shù)據(jù)為何"丟失"?
通過設置EnableCommNotification函數(shù)中的cbWriteNotify參數(shù)(在發(fā)送WM_COMMNOTIFY消息之前,通信設備驅(qū)動程序必須向應用程序出入隊列中寫入的字節(jié)數(shù)),可以使系統(tǒng)每收到固定個字符發(fā)出一WM_COMMNOTIFY消息,這對于固定長度消息型的通信是很方便的`。但實際應用時有時會發(fā)生接收數(shù)據(jù)"丟失"現(xiàn)象,即收到WM_COMMNOTIFY消息后從接收隊列讀出cbNotify個數(shù)據(jù)時,發(fā)現(xiàn)只有前面部分數(shù)據(jù)正確。
經(jīng)檢查,"丟失"現(xiàn)象是由于接收數(shù)據(jù)超時引起的,當通信對方時鐘頻率較低時,規(guī)定時間內(nèi)收不到cbWriteNotify指定的數(shù)據(jù)量,即所謂"超時",Windows照樣向應用程序發(fā)送帶CN_RECEIVE標志的WM_COMMNOTI
FY消息。然后,在應用程序輸入隊列數(shù)據(jù)讀出之前,Windows不再發(fā)送該類消息。