VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 用VB5.0开发通信软件的技巧
发表评论(0)作者:, 平台:, 阅读:10141, 日期:2000-03-25
用VB5.0开发通信软件的技巧


一 自己开发通信软件的必要性:


随着计算机应用领域的不断扩展,计算机之间的远程通信用得越来越广泛.进行计算机通信需要调制解调器(modem),电话线及通信软件.尽管市面上有许多商品通信软件,但是在许方情况下商品通信软件并不能满足实际工作的需要.这是因为通用的通信软件虽然能发送和接收文件,但有些时侯是不适用的.例如我们在开发一个EDI(电子数据交换)应用系统时,就需要把接收到的某个单证直接地自动地放到一个数据库中,作为一条记录。这种情况下采用通用的通信软件就不行了,需要开发自己专用的通信软件。

过去,开发通信软件对于一般的应用软件开发人员来说是比较困难的。而现在这件事已经变得容易多了。本文介绍如何利用VB5.0和MSCOMM控件开发通信软件。

要想自己开发通信软件,除了要掌握VB5.0的基本编程语言以外,还需知道一些微机通信的基本原理。如有关串行端口及调制解调器的基本知识,调制解调器的使用手册及AT命令集等。这在许多书中都可以找到。本文不再叙述。


二 有关预备知识


在PC机串行端口与调制解调器进行连接时,有十几根线进行信号传输。对于用MSCOMM控件编制通信软件来说,只需了解以下五根线的代号及作用。以下五根线的高电平/低电平状态分别对应MScomm控件的相应属性的True/False值。

(1)DTR线:PC发往MODEM,表示PC机是否已准备好。

(2)RTS线:PC发往MODEM,表示PC机是否允许modem发回数据.

(3)DSR线:MODEM发往PC,表示MODEM是否已做好操作准备

(4)CTS线:MODEM发往PC,表示MODEM是否允许发送数据

(5)CD线:MODEM发往PC,表示MOEDM已经与呼叫的远方MODEM处于连结状态


三 MSCOMM控件的属性及事件


VB5.0所带的通信控件MSCOMM易学易用。它只有约30个属性和事件。可以从VB5.0的联机帮助中找到它的全部资料。本文简述它的主要属性及事件,并加已归类整理。以下用MSCOMM1表示在窗体上设置的一个MSCOMM控件的名称


(一)通信参数设置


(1)CommPort属性

语法:MSCOMM1.CommPort[=Value]

作用:设置或返回联接MODEM的串口的编号。

值:用1,2,...表示串口COM1,COM2....


(2)Settings属性

语法:MSCOMM1.Settings[=Value]

作用:设置或返回通信参数。

值:String型。例入用"19200,N,8,1"表示传输速率为19200bps,没有奇偶校验位,8位数据位,1位停止位。


(3)Handshaking属性

语法:MSCOMM1.Handshaking[=Value]

作用与值:设置或返回硬件握手协议。指的是PC机MODEM之间为了控制流速而约定的内部协议。

0 没有握手协议。不考虑流量控制。

1 XON/XOFF。即在数据流中嵌如控制苻来进行流控。

2 RTS/CTS。既由信号线RTS/CTS自动进行流量控制。

3 两者皆可。

注:实践中我们发现选用2(即RTS/CTS)是很方便的。


(二)打开/关闭端口


(4)PortOpen属性

语法:MSCOMM1.PortOpen[=Value]

作用:打开或关闭端口。

值:Boolean型。设为True/False可以打开/关闭端口。


(三)发送数据

(5)OutBufferSize属性

语法:MSCOMM1.OutBufferSize[=Value]

作用:设置或返回传输缓冲区大小。

值:Integer型。传输缓冲区的字节数。例如可选1024。


(6)OutPut属性

语法:MSCOMM1.OutPut[=Variant]

作用:向传输缓冲区写数据流。

值:Variant型变量。

注:传输文本数据时,应将String型数据放入Variant变量,传输二进制数据(即按字节)时Byte型数组数据放入Variant变量


(四)接收数据

(7)InBufferSize属性

语法:MSCOMM1.InBufferSize[=Value]

作用:设置或返回接收缓冲区大小。

值:Integer型。接收缓冲区的字节数。例如可选1024。


(8)InputMode属性

语法:MSCOMM1.InputMode[=Value]

作用:设置或返回接收数据的数据类型。

值:0用Input属性接收文本型数据。

1用Input属性接收二进制数据。


(9)InBufferCount属性

语法:MSCOMM1.InBufferCount[=Value]

作用:返回接收缓冲区中已传到但还未取走的字符个数。

值:Integer型。


(10)Input属性

语法:MSCOMM1.Input[=Variant]

作用:将接收缓冲区中收到的数据读入变量。

值:Variant型变量。

注:当InputMode属性值为0(文本模式)时,变量中含String型数镜盜nputMode属性值为1(二进制模式)时,变量中含Byte型数组数据。


(五)状态控制

(11)DTREnabled属性

(12)RTSEnabled属性

(13)DSRHolding属性

(14)CTSHolding属性

(15)CDHolding属性


以上五个属性即如二所述,均取值TRUE/FALSE,用于读取或控制pc机与modem之间的交互状态。需运用好。例在读取到DSRHolding属性值为TRUE时再向MODEM发出命令。应当在载波检测到以后(CDHolding属性为TRUE)时再向MODEM发送数据。


(六)事件

MSCOMM控件把实际上是十七个事件归并为一个事件OnComm,用属性CommEvent的十七个值来区分不同的触发时机。主要有以下几个:


(1)CommEvent=1时:传输缓冲区中的字符个数已少于Sthreshold(可设置的属性值)个.

(2)CommEvent=2时:接收缓冲区中收到hreshold(可设置的属性值)个个字符.利用此事件可编写接收数据的过程。

(3)CommEvent=3时:CTS线发生变化.

(4)CommEvent=4时:DSR线发生变化.

(5)CommEvent=5时:CD线发生变化.

(6)CommEvent=6时:检测到振铃信号.

另外十个情况是可能发生的各种通信错误时触发。可参看有关资料.


四 通信软件参数设置


在自己编写的通信软件中,应包含进行通信参数设置的功能。主要就是可以设置端口号,波特率,数据位,停止位,奇偶校验位及设置硬件握手协议。

可在一个窗体上用下拉列表框,选择钮等由用户来选择。《保存》时,利用VB5.0的Settings函数将这些参数存储在WINDOWS95的系统注册表中。每次运行该软件时,先用GetSettings函数调出这些参数,并对Commport,Settings,Handshaking等属性赋值,来进行通信参数设置。


五 打开通信端口


在编写的通信软件的主窗体上,可以安排一个打开/关闭端口的菜单项或图形按钮。在打开端口时,可向MODEM发出命令,进行MODEM参数设置。可以象下面这样来编程:

(1)打开/关闭端口

MSComm1.PORTOPEN=NotMSComm1.PORTOPEN

(2)向MODEM发出DTR(已准备好)信号

OpenFlag=MSComm1.PORTOPEN

If OpenFlag Then

MSComm1.DTREnable=True

Else

MSComm1.DTREnable=False

End If

(3)打开时向MODEM发出一些命令来设置参数

S0=n(n>=1)自动应答.n为响铃次数

E0/E1关闭/打开命令字符回应

Q0/Q1modem返回/不返回结果码

M0/M1关闭/打开MODEM扬声器.

If OpenFlag Then

L1:

If MSComm1.CTSHolding Then

Outstring="ATS0=1E1Q0M0"+Chr(13)

MSComm1.Output=Outstring

GoTo LL

Else

GoTo L1

End If

End If

LL:...


也可以安排一些可变换颜色的指示灯来代表端口打开状态,CD线状态等,这样更形象生动。


六 拨号


进行拨号需向MODEM发出ATDT命令。可用如下语句:

cc="ATDT"+Trim(Text1.Text)+Chr(13)

MSComm1.Output=cc

其中TEXT1是窗体上让用户输入电话号的文本框。

为了使程序功能更强一些,可以增加<电话号码簿管理>,可以增加,修改,删除,查询电话号码。这与一般的数据库应用程序是一样的。


七 发送文件


拨号以后,程序要循环等待并随时判定是否接通。如果MODEM向PC的回应字符串中含有"Connect"或CDHolding属性值变为True(检测出载波),则表示已与远方MODEM连机了。这时就可以发送文件了。

发送文件开始以前,可打开一个显示发送信息的窗口。可在此窗口上显示要发送的文件名,总长度,已发送长度等信息。

设置以下全局变量,存放标志字符串,在发送及接收程序中均使用。

S_FILENAME="FILENAME"+Chr(5)+Chr(13)+Chr(10)

S_FILELEN="FILELEN"+Chr(5)+Chr(13)+Chr(10)

S_FILESTAR="FILESTAR"+Chr(5)+Chr(13)+Chr(10)


(1)打开文件:

要想把一个文件的全部字节都传送,需以二进制方式打开文件。可用如下语句

'得到下一个可用的文件号,放在整型变量hSend

hSend=FreeFile

'打开文件

Open SENDFN For BinaryAccessRead As hSend

LF&=LOF(hSend)'文件长度为LF&

其中变量SENDFN中含有由用户选定的要传送的文件名。


(2)发送文件名,文件长度,文件开始等信息字符串。

例如,我们设计成如下:

DIM VARC AS VARIANT

VARC=S_FILENAME

MSComm1.Output=VARC '发出"FILENAME"提示字串

VARC=SENDFN+Chr(13)+Chr(10)

TXRJ.MSComm1.Output=VARC '发出文件名

VARC=S_FILELEN

MSComm1.Output=VARC '发出"FILELEN"提示字串

VARC=Trim(Str(LF&))+Chr(13)+Chr(10)

MSComm1.Output=VARC '发出文件宽度

VARC=S_FILESTAR

'发出"FILESTART"提示字串,表示下面文件开始。

MSComm1.Output=VARC

然后程序倒计时,在发送信息窗口显示8,7,6,5,4,3,2,1,0.


(3)发送文件内容

用GET语句从文件读字节,用OUTPUT属性发送。

DIM SENDARR() AS BYTE '定义字节型数组

Sum=0'记录累计发送的字节数

BSIZE=MSComm1.OutBufferSize '每次发送的块大小

ReDim SENDARR(1 To BSIZE)

'循环发送

Do While Sum If LF&-Loc(hSend) BSIZE=LF&-Loc(hSend)

ReDim SENDARR(1 To BSIZE)

End If

Get hSend,,SENDARR '从文件取字节放入字节数组

SENDVAR=SENDARR '转放到Variant型变量

'当CTS线及CD线为高电平时才可发送,否则需等待。

T=Timer+60

L:

If MSComm1.CTSHolding And MSComm1.CDHolding Then

MSComm1.Output=SENDVAR '发送

Sum=Sum+BSIZE '累加计数

Label6.Caption=Str(Sum) '显示在发送窗口上

Else

If Timer GoToL '循环等待

Else

GoTo CLOSEFILE '等待时间超过60秒则退出

End If

End If

'等待系统处理完

Do

RET=DoEvents()

Loop Until MSComm1.OutBufferCount=0

Loop '循环语句结尾


文件发送完毕以后,关闭该文件。并关闭发送文件信息窗口。


八 接收MODEM回送的信息及接收文件


(一)设计要点:我们是如下进行设计的。

1.在主窗口上设一个多行显示的文本框,用来显示接收到的所有文本类型信息。

2.建立<收件箱>。实际上是一个数据库中的一个表.包含收件日期,文件名,文件长度,序号等字段。

3.利用事件触发机制来执行接收数据的过程。即编写mscomm1控件的OnCOMM事件的处理程序。

4.按以下方法来改变输入模式属性(InputMode)的值:通常使InputMode属性为文本模式。当发现接收到的字符串中有"FILESTAR"+Chr(5)+Chr(13)+Chr(10),按本软件规定表示传送的文件内容将开始,则将InputMode属性改为二进制模式。当文件内容接收完(由接收的字节数判断)再将InputMode属性改为文本模式。

5.利用本软件设计的标志字符串(见七)来控制进程,在发送及接收程序中均使用。


(二)MSCOMM1控件的OnCOMM事件的的处理程序

Private Static Sub MSComm1_OnComm()

Select Case MSComm1.CommEvent

Case comEvReceive '接收缓冲区收到Rthreshold个字符时触发

Dim VARC As Variant

Dim N As Long

Dim SJARR() As Byte

N=MSComm1.InBufferCount '接收缓冲区字符总数

If MSComm1.InputMode=0 Then '当输入模式为文本模式时,将收到的数据放到字符串变量。

MSComm1.InputLen=0

VARC=Space(N)

VARC=MSComm1.Input

Else '当输入模式为二进制模式时,将收到的数据放到字节数组。

ReDim SJARR(1 To N)

VARC=ARR

MSComm1.InputLen=N

VARC=MSComm1.Input

End If

ShowDATA TextTerm,N,VARC '调接收数据处理过程Showdata

End Select

EndSub


(三)接收数据处理过程ShowData


Public Static Sub ShowData(TermAsControl,NAsLong,DATAAsVariant)

'参数:Term(主窗体上的文本框,用于显示接受数据)

'N为本次接收到的字节数

'DATA(接收到的数据.Variant型)

(变量定义部分:略)

'(一)非文件传输情形(接收的是字符串)

If not mscomm1.InputMode=0 Then

GoTo L2

End If

'(1)把新接收的字符数据放到文本框TERM末尾

Term.SelStart=Len(Term.Text)

Term.SelLength=0

Term.SelText=DATA

'(2)未找到文件传输开始标志就结束此过程

W_FILESTAR=InStr(1,Term.Text,S_FILESTAR,0)

If W_FILESTAR=0Then

Exit Sub

End If

'(3)以下为找到文件传输开始标志的情况

'(3-1)找文件名及文件长度

W_FILENAME=InStr(1,Term.Text,S_FILENAME,0)

W_FILELEN=InStr(1,Term.Text,S_FILELEN,0)

FN=Mid(Term.Text,W_FILENAME+11,(W_FILELEN-W_FILENAME-13))

'(3-2)打开接收文件

hJS=FreeFile

JSFN=Pathc+"\SJFILE\S"+Trim(Str(NO))+"_"+FN

Open JSFN For BinaryAccessWrite As hJS

'(3-3)收件箱增加新记录

W_FILENAME=InStr(1,Term.Text,S_FILENAME,0)

W_FILELEN=InStr(1,Term.Text,S_FILELEN,0)

FN=Mid(Term.Text,W_FILENAME+11,(W_FILELEN-1)-(W_FILENAME+11))

FL=Mid(Term.Text,W_FILELEN+11,W_FILESTAR-(W_FILELEN+10))

SENDLEN=Val(FL) '应收总字节数SENDLEN

'以下SJRS是已打开的收件箱对应的记录集型变量

SJRS.AddNew '增加一新记录

SJRS!SJRQ=Now' 写入收件日期

SJRS!SJFILE=FN '写入收件的文件名

SJRS!SJLEN=Val(FL) '写入收件的长度

SJRS!FILENO=NO '写入收件的序号

'(3-4)显示文件接收窗口

JSLEN=0

TXINPUT.Show

'(3-5)改变输入模式属性InputMode为二进制模式

TXRJ.MSComm1.InputMode=comInputModeBinary

'(4)等待几秒,显示876543210

ExitSub

'(二)文件传输状态处理

L2:

ReDim JSARR(0 To N-1)

JSARR=DATA '将字节流放入字节型数组

'将字节型数组中的数据写入已打开的接收文件

Put hJS,,JSARR

JSLEN=JSLEN+N '本次已累计收到的字节数

'已收字节数与文件总长相比较

If JSLEN ExitSub

End If

'转此为文件传输已结束--

'关闭接收文件

Close hJS

'提交收件箱表的新增记录

SJRS.Update

'修改文本显示

W_FILENAME=InStr(1,Term.Text,S_FILENAME,0)

Term.SelStart=W_FILENAME-1

Term.SelLength=Len(Term.Text)

Term.SelText=""

FL="文件"+FN+"接收结束"+Chr(13)+Chr(10)

Term.Text=Term.Text&FL

'关闭收件窗口

Unload TXINPUT

'改变InputMode属性为文本模式

TXRJ.MSComm1.InputMode=0

Exit Sub

End Sub


以上以发送和接收文件为例介绍了我们是如何使用VB5.0及MSCOMM控件来开发自己的的通信软件的。掌握了以上基本技术,就可以稍加改变来开发自己的各种专用通信软件。例如发送数据库的一条记录,并使接收方把接收到的数据也放在数据库中。也可以进行数据加密/解密传输等。总之,学习怎样使用VB5.0及MSCOMM控件来开发自己的的通信软件是十分有用的。