用VB开发通信软件的技巧

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

[VisualBasic]用VB开发通信软件的技巧
一自己开发通信软件的必要性:
---- 随着计算机应用领域的不断扩展, 计算机之间的远程通信用得越
来越广泛. 进行计算机通信需要调制解调器(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 属性
---- 语法: mPort [=&118alue]
---- 作用:设置或返回联接 MODEM 的串口的编号。

---- 值: 用1,2, ... 表示串口 COM1,COM2 ....
---- (2) Settings 属性
---- 语法: MSCOMM1.Settings [=&118alue]
---- 作用:设置或返回通信参数。

---- 值: String 型。

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

---- (3) Handshaking 属性
---- 语法: MSCOMM1.Handshaking [=&118alue]
---- 作用与值:设置或返回硬件握手协议。

指的是PC 机MODEM 之间为了控制流速而约定的内部协议。

---- 0 没有握手协议。

不考虑流量控制。

---- 1 XON/XOFF。

即在数据流中嵌如控制苻来进行流控。

---- 2 RTS/CTS 。

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

---- 3 两者皆可。

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

---- (二)打开/ 关闭端口
---- (4) PortOpen 属性
---- 语法: MSCOMM1.PortOpen [=&118alue]
---- 作用:打开或关闭端口。

---- 值: Boolean 型。

设为 True/False 可以打开/ 关闭端口。

---- ( 三) 发送数据
---- (5) OutBufferSize 属性
---- 语法: MSCOMM1.OutBufferSize [=&118alue]
---- 作用:设置或返回传输缓冲区大小。

---- 值: Integer 型。

传输缓冲区的字节数。

例如可选 1024 。

---- (6) OutPut 属性
---- 语法: MSCOMM1.OutPut [=Variant]
---- 作用:向传输缓冲区写数据流。

---- 值: Variant 型变量。

---- 注:传输文本数据时, 应将 String 型数据放入 Variant 变量,传输二进制数据( 即按字节) 时, 应将 Byte 型数组数据放入 Variant 变量
---- ( 四) 接收数据
---- (7) InBufferSize 属性
---- 语法: MSCOMM1.InBufferSize [=&118alue]
---- 作用:设置或返回接收缓冲区大小。

---- 值: Integer 型。

接收缓冲区的字节数。

例如可选 1024 。

---- (8) InputMode 属性
---- 语法: MSCOMM1.InputMode [=&118alue]
---- 作用:设置或返回接收数据的数据类型。

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

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

---- (9) InBufferCount 属性
---- 语法: MSCOMM1.InBufferCount [=&118alue]
---- 作用:返回接收缓冲区中已传到但还未取走的字符个数。

---- 值: Integer 型。

---- (10) Input 属性
---- 语法: MSCOMM1.Input [=Variant]
---- 作用:将接收缓冲区中收到的数据读入变量。

---- 值: Variant 型变量。

---- 注:当InputMode 属性值为 0(文本模式)时, 变量中含 String 型数据。

---- 当InputMode 属性值为 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 函数将这些参数存储在WINDOWS 95 的系统注册表中。

每次运行该软件时,先用 GetSettings 函数调出这些参数,并
对Commport,Settings,Handshaking 等属性赋值,来进行通信参数设置。

五打开通信端口
---- 在编写的通信软件的主窗体上,可以安排一个打开/ 关闭端口的
菜单项或图形按钮。

在打开端口时,可向 MODEM 发出命令,进行MODEM 参数设置。

可以象下面这样来编程:
'(1)打开/关闭端口
MSComm1.PORTOPEN = Not MSComm1.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/Q1 modem返回/不返回结果码
'M0/M1 关闭/打开MODEM扬声器.
If OpenFlag Then
L1:
If MSComm1.CTSHolding Then
Outstring = "AT S0=1 E1 Q0 M0 " + 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 Binary Access Read 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 < LF&
If LF& - Loc(hSend) < BSIZE Then
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 < T Then
GoTo L '循环等待
Else
GoTo CLOSEFILE '等待时间超过 60秒则退出
End If
End If
' 等待系统处理完
Do
RET = DoEvents()
Loop Until MSComm1.OutBufferCount = 0
Loop '循环语句结尾
---- 文件发送完毕以后, 关闭该文件。

并关闭发送文件信息窗口。

八接收 MODEM 回送的信息及接收文件
---- ( 一) 设计要点: 我们是如下进行设计的。

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

建立< 收件箱> 。

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

,li> 利用事件触发机制来执行接收数据的过程。

即编写 mscomm1 控件的OnCOMM 事件的处理程序。

按以下方法来改变输入模式属性(InputMode)的值:通常使InputMode 属性为文本模式。

当发现接收到的字符串中有 "FILESTAR" + Chr(5) + Chr(13) + Chr(10), 按本软件规定表示传送的文件内容将开始,则将InputMode 属性改为二进制模式。

当文件内容接收完(由接收的字节数判断)再将InputMode 属性改为文本模式。

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

---- ( 二) MSCOMM1 控件的 OnCOMM 事件的的处理程序
Private Static Sub MSComm1_OnComm()
Select Case mEvent
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
End Sub
---- (三) 接收数据处理过程 ShowData
Public Static Sub ShowData(Term As Control, _
N As Long, DATA As Variant)
'参数: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 = 0 Then
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 Binary Access Write 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 '(7)等待几秒, 显示 8 7 6 5 4 3 2 1 0
Exit Sub
'(二)文件传输状态处理------------
L2:
ReDim JSARR(0 To N - 1)
JSARR = DATA '将字节流放入字节型数组
'将字节型数组中的数据写入已打开的接收文件
Put hJS, , JSARR
JSLEN=JSLEN+N ’本次已累计收到的字节数
' 已收字节数与文件总长相比较
If JSLEN < SENDLEN Then
Exit Sub
End If
' 转此为文件传输已结束------
'关闭接收文件
Close hJS
'提交收件箱表的新增记录
SJRS.Update
'修改文本显示
W_FILENAME = InStr(1, Term.Text, S_FILENAME, 0)。

相关文档
最新文档