📄 170.htm
字号:
<p>开发通信软件的技术与技巧 </p>
<p></p>
<p>【提要】随着计算机应用领域的不断扩展,计算机之间的远程通信用得也越来越广泛,计算机间的远程通信所使用的通信软件,在市面上可以买到,但是通用的通信软件虽然能发送和接收文件,在许方情况下这些通信软件并不能满足实际工作的需要。本文就这一技术进行了探讨,介绍了有关的知识和技术,并由实例分步骤说明如何进行通信软件的开发。 </p>
<p></p>
<p>一、前言 </p>
<p> 本文将以VB5.0所带的通信控件MSCOMM进行通信软件的开发,它有约30个属性和事件(可以从联机帮助中找到其使用资料)。本文简述它的主要属性及事件,并归类整理。 </p>
<p>利用串行端口与调制解调器进行连接时,对于用MSCOMM控件编制通信软件来说,只需了解以下五根线的代号及作用。以下五根线的高电平/低电平状态分别对应MScomm控件的相应属性的True/False值。 </p>
<p> (1)DTR线:PC发往MODEM,表示PC机是否已准备好。 </p>
<p> (2)RTS线:PC发往MODEM,表示PC机是否允许modem发回数据. </p>
<p> (3)DSR线:MODEM发往PC,表示MODEM是否已做好操作准备 </p>
<p> (4)CTS线:MODEM发往PC,表示MODEM是否允许发送数据 </p>
<p>(5)CD线:MODEM发往PC,表示MOEDM已经与呼叫的远方MODEM处于连结状态 </p>
<p></p>
<p>二、MSCOMM控件的属性 </p>
<p>属性 </p>
<p>值 </p>
<p>作用 </p>
<p>CommPort </p>
<p>用1,2,...表示串口COM1,COM2.... </p>
<p>设置或返回联接MODEM的串口的编号 </p>
<p>Settings </p>
<p>例用"19200,N,8,1"表示传输速率为19200bps,没有奇偶校验位,8位数据位,1位停止位。 </p>
<p>设置或返回通信参数。 </p>
<p>Handshaking </p>
<p>0没有握手协议,不考虑流量控制。 </p>
<p>1XON/XOFF,即在数据流中嵌如控制苻来进行流控。 </p>
<p>2RTS/CTS,既由信号线RTS/CTS自动进行流量控制(常用)。 </p>
<p>3两者皆可。 </p>
<p>设置或返回硬件握手协议,指的是PC机MODEM之间为了控制流速而约定的内部协议。 </p>
<p>PortOpen </p>
<p>True/False可以打开/关闭端口。 </p>
<p>打开或关闭端口。 </p>
<p>OutBufferSize </p>
<p>传输缓冲区的字节数,如选1024。 </p>
<p>设置或返回传输缓冲区大小。 </p>
<p>OutPut </p>
<p>Variant型变量。 </p>
<p>向传输缓冲区写数据流。 </p>
<p>传输文本数据时,应将String型数据放入Variant变量,传输二进制数据(即按字节)时,应将Byte型数组数据放入Variant变量 </p>
<p>InBufferSize </p>
<p>接收缓冲区的字节数,如选1024。 </p>
<p>设置或返回接收缓冲区大小。 </p>
<p>InputMode </p>
<p>0用Input属性接收文本型数据。 </p>
<p>1用Input属性接收二进制数据。 </p>
<p>设置或返回接收数据的数据类型。 </p>
<p>InBufferCount </p>
<p>Integer型 </p>
<p>返回接收缓冲区中已传到但还未取走的字符个数。 </p>
<p>Input </p>
<p>当InputMode属性值为0(文本模式)时,变量中含String型数据。 </p>
<p>当InputMode属性值为1(二进制模式)时,变量中含Byte型数组数据。 </p>
<p>将接收缓冲区中收到的数据读入变量。 </p>
<p>DTREnabled </p>
<p>RTSEnabled </p>
<p>DSRHolding </p>
<p>CTSHolding </p>
<p>CDHolding </p>
<p>均取值TRUE/FALSE </p>
<p>用于读取或控制pc机与modem之间的交互状态。需运用好。例如,应在读取到DSRHolding属性值为TRUE时再向MODEM发出命令。应当在载波检测到以后(CDHolding属性为TRUE)时再向MODEM发送数据。 </p>
<p></p>
<p>三、MSCOMM控件的触发事件 </p>
<p> MSCOMM控件只使用一个事件OnComm,用属性CommEvent的十七个值来区分不同的触发时机。主要有以下几个: </p>
<p> (1)CommEvent=1时:传输缓冲区中的字符个数已少于Sthreshold(可设置的属性值)个。 </p>
<p> (2)CommEvent=2时:接收缓冲区中收到hreshold(可设置的属性值)个个字符,利用此事件可编写接收数据的过程。 </p>
<p> (3)CommEvent=3时:CTS线发生变化。 </p>
<p> (4)CommEvent=4时:DSR线发生变化。 </p>
<p> (5)CommEvent=5时:CD线发生变化。 </p>
<p> (6)CommEvent=6时:检测到振铃信号。 </p>
<p> 另外十种情况是通信错误时产生,即错误代码。 </p>
<p></p>
<p>四、通信软件程序实现 </p>
<p> 1、首先是通信参数设置,主要就是可以设置端口号,波特率,数据位,停止位,奇偶校验位及设置硬件握手协议,这些设置较为简单。 </p>
<p>2、向MODEM发出DTR(已准备好)信号,如下例程: </p>
<p>If MSComm1.PORTOPEN Then </p>
<p>MSComm1.DTREnable=True </p>
<p>Else </p>
<p>MSComm1.DTREnable=False </p>
<p>EndIf </p>
<p>3、打开时向MODEM发出一些命令来设置参数,其中S0=n(n>=1)自动应答.n为响铃次数;E0/E1关闭/打开命令字符回应;Q0/Q1modem返回/不返回结果码;M0/M1关闭/打开MODEM扬声器,例程如下: </p>
<p>If MSComm1.PORTOPEN Then </p>
<p>Do While not MSComm1.CTSHolding : loop </p>
<p>Outstring="ATS0=1E1Q0M0"+Chr(13) </p>
<p>MSComm1.Output=Outstring </p>
<p>End if </p>
<p>4、进行拨号设计,需向MODEM发出ATDT命令,如下语句: </p>
<p>MSComm1.Output="ATDT"+Trim(“电话号码”)+Chr(13) </p>
<p>5、拨号以后发送数据文件,程序要循环等待并随时判定是否接通。如果MODEM向PC的回应字符串中含有"Connect"或CDHolding属性值变为True(检测出载波),则表示已与远方MODEM连机了,此时可以传输数据。 </p>
<p>程序设计发送及接收程序时,需要以下定义: </p>
<p>S_FILENAME = "NAME" + Chr(5) + Chr(13) + Chr(10) </p>
<p>S_FILELEN = "LENTH" + Chr(5) + Chr(13) + Chr(10) </p>
<p>S_FILESEND = "BEGIN" + Chr(5) + Chr(13) + Chr(10) </p>
<p></p>
<p>Sub OpenFileToSend() 注释:打开一个欲发送的文件 </p>
<p>HSend = FreeFile </p>
<p>Open SENDFN For Binary As hSend 注释:SENDFN中含有由用户选定的要传送的文件名。 </p>
<p>LF&=LOF(hSend) 注释:文件长度为LF& </p>
<p>注释:开始发送文件名,文件长度,文件开始等信息字符串。 </p>
<p>Dim Data as Vrait </p>
<p>Data = S_FILENAME </p>
<p>MSComm1.Output=Data 注释:发出"FILENAME"文件名字串的提示信息 </p>
<p>Data = SENDFN +Chr(13)+Chr(10) </p>
<p>MSComm1.Output=Data 注释:发出文件名 </p>
<p>Data = S_FILELEN </p>
<p>MSComm1.Output=DATA 注释:发出"FILELEN"提示字串 </p>
<p>Data = Trim(Str(LF&))+Chr(13)+Chr(10) </p>
<p>MSComm1.Output=Data 注释:发出文件大小 </p>
<p>Data = S_FILESTAR </p>
<p>MSComm1.Output=Data 注释:发出"FILESTART"提示信息,表示下面文件开始。 </p>
<p></p>
<p>Dim Sendarr() as byte 注释:定义字节型数组 </p>
<p>Sum=0 注释:记录累计发送的字节数 </p>
<p>BSIZE=MSComm1.OutBufferSize 注释:每次发送的块大小 </p>
<p>ReDim Sendarr(1 To BSIZE) 注释:重新定义读取缓冲 </p>
<p>Do While Sum<LF& 注释:循环发送 </p>
<p>If LF&-Loc(hSend)<BSIZE Then </p>
<p>BSIZE=LF&-Loc(hSend) </p>
<p>ReDim Sendarr(1 To BSIZE) </p>
<p>End If </p>
<p>Get hSend ,, SENDARR 注释:从文件取字节放入字节数组 </p>
<p>Sendvar=Sendarr 注释:转放到Variant型变量 </p>
<p>注释:当CTS线及CD线为高电平时才可发送,否则需等待。 </p>
<p>T=Timer+60 </p>
<p>L: </p>
<p>If MSComm1.CTSHolding And MSComm1.CDHolding Then </p>
<p>MSComm1.Output=Sendvar 注释:发送 </p>
<p>Sum = Sum + BSIZE注释:累加计数 </p>
<p>Else </p>
<p>If Timer < T Then </p>
<p>Go To L 注释:循环等待 </p>
<p>Else </p>
<p>Go To CLOSEFILE 注释:等待时间超过60秒则退出 </p>
<p>End If </p>
<p>End If </p>
<p>注释:等待系统处理完 </p>
<p>Do </p>
<p>RET = DoEvents() </p>
<p>Loop Until MSComm1.OutBufferCount = 0 </p>
<p>Loop 注释:循环发送完毕。 </p>
<p></p>
<p>6、接收MODEM送回的信息和数据文件,该过程是编写mscomm1控件的OnCOMM事件的处理程序来完成。为了接收文本类型的握手信号,通常使InputMode属性为文本模式。当发现接收到的字符串中有"FILESTAR"+Chr(5)+Chr(13)+Chr(10),则将InputMode属性改为二进制模式。当文件内容接收完(由接收的字节数判断)再将InputMode属性改为文本模式。例程如下: </p>
<p>Private Static Sub MSComm1_OnComm() </p>
<p>Select Case MSComm1.CommEvent </p>
<p>Case comEvReceive 注释:接收缓冲区收到Rthreshold个字符时触发 </p>
<p>Dim DATA As Variant </p>
<p>Dim N As Long </p>
<p>Dim SJARR() As Byte </p>
<p>N=MSComm1.InBufferCount 注释:接收缓冲区字符总数 </p>
<p>If MSComm1.InputMode=0 Then注释:文本模式时,将收到的数据放到字符串变量。 </p>
<p>MSComm1.InputLen=0 </p>
<p>DATA = Space(N) </p>
<p>DATA = MSComm1.Input </p>
<p>Else 注释:二进制模式时,将收到的数据放到字节数组。 </p>
<p>ReDim S JARR(1ToN) </p>
<p>DATA=ARR </p>
<p>MSComm1.InputLen=N </p>
<p>DATA=MSComm1.Input </p>
<p>End If </p>
<p>注释:其它case情况略 </p>
<p>End Select </p>
<p>End Sub </p>
<p></p>
<p>7、关于接收到的数据的处理例程: </p>
<p>Public Static Sub HandleData (Disp As Control,N As Long,DATA As Variant) </p>
<p>注释:参数:Disp(文本框,用于显示接受数据) </p>
<p>注释:N为本次接收到的字节数 </p>
<p>注释:DATA(接收到的数据.Variant型) </p>
<p>If not mscomm1.InputMode=0 Then 注释:接收的是字符串 </p>
<p>Go To L2 </p>
<p>End If </p>
<p>Disp.SelStart = Len ( Disp.Text) </p>
<p>Disp.SelLength = 0 </p>
<p>Disp.SelText = DATA 注释:显示字符数据 </p>
<p>If InStr(1,Disp.Text,S_FILESTAR,0)=0 Then 注释:若没有开始标志就结束此过程 </p>
<p>ExitSub </p>
<p>EndIf </p>
<p>V_FILENAME = InStr(1,Disp.Text,S_FILENAME,0) 注释:找文件名及文件长度 </p>
<p>V_FILELEN = InStr(1,Disp.Text,S_FILELEN,0) </p>
<p>FN = Mid(Disp.Text,V_FILENAME+11,(V_FILELEN-V_FILENAME-13)) </p>
<p>HJS = FreeFile注释:打开接收文件 </p>
<p>JSFN = Pathc+"\SJFILE\S"+Trim(Str(NO))+"_"+FN </p>
<p></p>
<p>Open JSFN For Binary As HJS </p>
<p>V_FILENAME = InStr(1,Disp.Text,S_FILENAME,0) </p>
<p>V_FILELEN = InStr(1,Disp.Text,S_FILELEN,0) </p>
<p>FN = Mid(Disp.Text,V_FILENAME+11,(V_FILELEN-1)-(V_FILENAME+11)) </p>
<p>FL = Mid(Disp.Text,V_FILELEN+11,V_FILESTAR-(V_FILELEN+10)) </p>
<p>SENDLEN = Val(FL) 注释:应收总字节数SENDLEN </p>
<p></p>
<p>ReDim JSARR(0 To N-1) </p>
<p>JSARR=DATA 注释:将字节流放入字节型数组 </p>
<p>Puth JS , , JSARR 注释: 写入已打开的接收文件 </p>
<p>JSLEN=JSLEN+N 注释:本次已累计收到的字节数 </p>
<p>Close HJS </p>
<p>End Sub </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -