前言:在行业用户中,大多数基层计算机应用系统采用UNIX作OS,用支持RS232连接的终端做业务处理,打印也通过终端实现。随着PC机拥有量的不断增加,通过网卡、HUB,就可把服务器与PC 机连接起来,然后在PC机上用TELNET登录上服务器,就可把PC机作终端用了。美中不足的是无法在PC机上实现终端打印,某些TELNET类软件,也只支持透明打印方式的一种指令,无法满足终端打印的要求。为了减少硬件的投入,提高现有设备的利用率,我们自己动手做了一个这样的软件,能使PC机完全代替终端使用,暂且称该软件为TELVT100,下面来一步一步实现它。
首先,考虑一下TELVT100要实现哪些功能:一、PC机与服务器的连接;二、能虚拟终端显示,目前,绝大部分UNIX上的应用系统支持VT100终端类型,因此,主要实现VT100终端类型的虚拟;三、把打印内容进行转换并送到与PC机相连的打印机上。
现在,分步骤对以上三部分说明,我们采用VB5.0作为开工具,由于程序条数较多,所以只列出与主要文字叙述相关的部分程序段。
‘变量的定义及初始化
Public Ztdi As Integer
Public IPAddR As String
Public RmtPtr as Integer
Public DaBulen as Long
......
Private Sub Form_Load() ‘初始化处理
Ztdi = Printer.Font.Size ‘打印字体大小
IPAddR = "32.145.24.1" ‘设置服务器的IP地址
RmtPtr = 0 ‘指令指针
DaBuLen = 0 ‘打印缓存大小
Winsock.Protocol = 0 ‘设定协议为TCP/IP
......
End Sub
一、 PC机与服务器的TELNET连接
要实现PC机与服务器的TELNET协议连接,必须先以TCP/IP协议连接PC机与服务器。给服务器端加网卡,并对网卡和TCP/IP协议进行设置,开放TELNET连接,设置端口地址为23。给PC机装上网卡,并配置网卡和TCP/IP协议。我们在PC机上编制相应的客户端程序,来实现TCP/IP连接。在这里主要用到VB中Winsock控件,下面了解一下它的有关性能。它提供了访问TCP/IP网络服务的方便途径,用它编写客户端应用程序,不必了解TCP/IP的细节,通过设置控件的属性并调用其方法就可连接到服务器上去,即把控件的RemoteHost属性设置为服务器的IP 地址,把RemotePort属性设置为服务器“侦听”的端口地址(上文提到的端口地址23),然后调用Connect方法实现与指定的IP地址服务器连接。建立连接后,服务器与PC机就可以互相收发数据。为了发送数据,要调用SendData方法。当客户端接收到数据时会发生 DataArrival 事件,在DataArrival事件内调用GetData方法就可获取数据。
连接建好后,PC机与服务器用TELNET协议命令建立协调机制。命令共有15条,每条命令前都要加上字符IAC(255),指出紧跟着的字符是命令。代码250和代码240用作命令的分界符,其余命令可分为两类。(一)基本命令:由代码241-249代表,它们执行TELNET的基本功能;(二)磋商选择命令:由代码251-254表示,这类命令主要实现两进程间磋商各种可选扩充功能。命令列表(1),详细解释,请查阅有关资料。
二、 实现VT100终端类型的虚拟
(一)、在有关窗体上加入一个TEXT控件,设为Text1,在Text1.KeyPress事件中,获得PC机的键盘输入,然后把相应键值变更为VT100终端键盘所对应的键值,把该值用Winsock控件的SendData方法发送给服务器,并禁止向TEXT控件的输出。
(二)、服务器接收键值后,作出相应的处理,并把输出的内容发送给对应的客户端,我们在Winsock控件的DataArrival事件中调用Winsock控件的GetData方法,来获得服务器发来的数据。
(三)、我们获得的从服务器发来的数据中,包含终端的控制指令。必须把控制指令分离出来,并做相应处理,同时把显示数据送到显示界面的指定位置。有关VT100终端指令的详细说明,请查阅有关技术手册,这里以光标定位指令ESC[Pr;Pc H举例说明。该指令的解释为:把显示界面的光标移动到第Pr行,第Pc列,Pr、Pc均为10进制数字,Pr值在1-24中,Pc值在1-80中。我们可把显示界面看做24X80的矩阵,每一个矩阵点上是一个字符,假设Pr=10,Pc=30,那么对该指令的执行结果,就是把对应光标位置的指针移到显示界面的显存偏移(10-1)*80+30的地方。具体实现过程如下:
‘***接收键盘输入、与服务器连接并向服务器发送***
Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim ch as String
‘判断网络连接是否处于正常状态
If Winsock1.State <> 0 And Winsock1.State <> 7 Then
ch = MsgBox("网络异常,请重新连接!")
KeyAscii = 0 ‘封锁键盘输入
Exit Sub ‘退出本事件
End If
If Winsock1.State = 0 Then ‘网络处于断开状态
IPADDR=Winsock1.RemoteHost
Winsock1.Connect IPAddR, 23 ‘与服务器连接
Else
Winsock1.SendData StrConv(Chr(KeyAscii), 8) ‘向服务器发送键盘输入
End If
KeyAscii = 0 ‘禁止向Text控件送键值
End Sub
‘***接收服务器向客户端发送的数据***
Private Sub newRecdata(CHRR As Variant) ‘虚拟终端处理函数
......
Print_ComX CHRR ‘调用打印指令处理函数
......
End Sub
Private Sub Telnet_Com(CHRR As Variant) ‘TELNET指令过滤函数
‘要把相应的应答指令直接发送给服务器
......
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) ‘数据到达以后,触发该事件
Dim CHRR As Variant
Winsock1.GetData CHRR ‘读取接收到的数据
Telnet_Com CHRR ‘TELNET指令过滤函数
newRecdata CHRR ‘虚拟终端处理函数
End Sub
三、 在PC机上实现终端打印
在终端机上主要有屏幕打印、拷贝打印、透明打印、控制打印、格式打印等打印形式,一般用在业务处理上的主要用透明打印和控制打印,这里主要介绍透明打印和控制打印。
(一)、透明打印的实现
在透明打印方式下,终端从服务器收到的字符除(11H)和(13H)外均不处理,全部送到打印机去,这种方式一般适用于带有汉字字库的打印机。应用程序发出ESC[5i控制指令,指出随后送出的字符是透明打印的内容,发出ESC[4i控制指令指出透明打印结束。根据以上叙述,在用Winsock控件的GetData方法获得的字符串中出现ESC[5i控制指令时,就要把随后的字符送到打印端口,而不是送到显示界面对应的显存,在GetData方法获得的字符串中出现ESC[4i控制指令时,就要把随后的字符送到显示界面对应的显存,而停止送到打印端口。假设打印机接在LPT1端口,把字符串送到打印机的例程如下:
Private Print_ComT1(DayBuf as String) ‘透明打印处理函数
......
Open "LPT1:" For Binary Access Write As #1 ‘把打印机作为文件打开
If DaBuLen > 0 Then ‘断判是否有打印数据
Put #1, , StrConv(DayinBuf, vbUnicode) ‘把数据送到打印机
End If
Close #1
......
End Sub
(二)、控制打印的实现
控制打印的实现比透明打印相对而言要复杂些,在控制打印方式下,打印的汉字字形、行距、字距控制等均使用终端命令实现,对打印机的要求是能支持图形打印。当终端收到ESC[/5i控制指令时,终端对随后收到的字符串,作为控制打印的内容(内含打印属性命令)进行处理,当终端收到ESC[/4i控制指令时,结束控制打印。控制打印的打印属性命令有几种,详细解释,请查阅相关资料,这里以ESC[/PsT命令来举例。Ps=0时,字符大小正常;Ps=1时,字符横向放大到2倍;Ps=2时,字符纵向放大到2倍;Ps=3时,字符横、纵各放大到2倍。显然,从上面的说明可以看出,打印属性命令,必须由TELVT100程序来解释,并对有关打印字符串进行处理,然后将处理过的内容交给打印机。这里将用到一个VB当中的对象PRINTER来完成控制打印功能,使用PINNTER对象,我们可以实现与打印机的通讯。用图形方法在 Printer 对象上绘制文本和图形后,可用 EndDoc 方法直接将打印信息送到打印机上。这里主要用到Printer对象的Print方法,它的功能就是把指定字符串送到Printer 对象上,还要用到Font属性等,具体用法举例说明如下:
Private Static Sub Print_Com2(Dayinbuf as String) ‘控制打印处理函数
Dim PPart() As Byte
Dim i, j As Long
Dim Combuf(12) as Byte
Dim CombufPtr As Long
......
For i = 0 To DaBuLen - 1
Select Case DayinBuf(i)
......
If CombufPtr <> 0 Then ‘判断是否有打印内容
Printer.Print StrConv(PPart, vbUnicode) ‘把待打印内容送到Printer打印对象
CombufPtr = 0 ‘指针复位
......
Select Case Combuf(RmtPtr)
Case Asc("T") ‘打印属性指令ESC[/Ps T
Select Case Combuf(RmtPtr - 1)
Case 48
Printer.Font.Size = Ztdi ‘字体为正常大小
......
Case 51
Printer.Font.Size = 2 * Ztdi ‘字体横、纵各放大到二倍
......
End Select
......
End Select
......
End Select
.....
next i
If CombufPtr <> 0 Then
Printer.Print StrConv(PPart, vbUnicode) ‘把待打印内容送到Printer打印对象
......
Printer.EndDoc
End If
End Sub
另外,在透明打印的实现上,可以采用控制打印的实现方法,这里涉及到对打印机指令进行解释的问题。在与本地服务器的连接上,可以象终端一样,把连接到终端的线缆直接连接到PC机的RS232口上,然后在TELVT100程序中加入MSCOMM控件,设置适当的通讯参数,用该控件的Input、Output方法进行数据收发,可以完全模仿终端使用。
经过以上各个过程,我们的TELVT100就近在眼前了。由于篇幅所限,不能面面具到,只给大家提供一个主体框架,想起到抛砖引玉的效果,希望和感兴趣的各位一起分享成功带来的欢乐。本程序已经被试用了一段时间,反映情况良好。
结束语:现在国内正流行数据的整合、集中,行业用户的业务处理系统在上一级部门的服务器上运行,基层单位往往采用终端服务器通过数据专线远程连接到上级部门。使用TELVT100这样的程序,可以不用终端服务器,而直接用PC机远程登录到业务处理系统服务器,进行业务处理。
-
vb教程之自己动手编制支持终端打印的TELNET程序
本栏文章均来自于互联网,版权归原作者和各发布网站所有,本站收集这些文章仅供学习参考之用。任何人都不能将这些文章用于商业或者其他目的。( Pfan.cn )
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比