请注意如果你是用VB6,在装载此工程之前,请先安装ThreeD32.OCX。该文件可在VB6的安装盘中的common\tools\vb\controls目录中找到,同时在这个目录中还有一个Vbctrl.reg文件。将这两个文件拷贝到windows\system目录下,用regsvr32注册后,运行Vbctrl已获取该控件的设计许可证。另外还要注意的是,源程序的注释部分很多是乱码,至少在我的机上如此。不过不影响程序运行。
本示例程序允许你通过选择通信协议同远程服务器连接。通过该程序你可以使用几乎所有的Internet服务,例如收发电子邮件,FTP等。一旦建立连接后,你就可以向服务器发送命令并接收来自服务器的回应了。该程序的工作方式有点象DOS操作。本程序并不是一个有完全功能的程序,因此它对最终用户来讲一点用也没有。它的目的是让你明白网络协议的基本原则,一旦你了解了两台计算机是如何通过Internet连接的话,对于快速开发Internet程序来说唯一的障碍就是缺乏足够的VB编程知识了。其实Internet编程最核心的东西就是字符串的处理。无论你选择哪种网络协议实际上都是在收发字符串。下图是本程序的工作界面。
Winsock Terminal是一个小巧且易于明白的应用程序。我们可以把我们要做的事分为六步:
用户界面开发。
建立同远程计算机的联系
编写代码,处理接收到消息
编写代码,处理用户输入的命令并发送给远程计算机
关闭与远程计算机的连接
开发服务子程序
用户界面开发
本程序用到两个窗体,除上面你所见到的外,还有一个名为frmConnect的窗体,如下图。用户可在该窗体中输入服务器的地址并选择所需的网络协议。程序的主窗体(如上图)包含三个部份:工具栏、状态栏和工作区。前两个分别用到了ToolBar和StatusBar这两个控件,而工作区则是由一文本框控件组成的。当同远程计算机建立了连接后,工具栏的右边会显示发出及接收的字节数。
状态栏中显示的信息表明Winsock控件当前的工作情况。另外为了能使工作区的大小随窗体大小的改变而改变,我们须将下面的代码放在窗体的Resize事件中。
Private Sub Form_Resize()
On Error Resume Next
With Me
txtCommand.Move .ScaleLeft, _
.ScaleTop + ToolBar.Height, _
.ScaleWidth, .ScaleHeight - _
ToolBar.Height - StatusBar.Height
End With
End Sub
建立与服务器的连接
为建立与服务器的连接,用户必须首先单击“连接”按钮,此时会弹出一个“连接到...”对话框。在远程服务器地址栏中输入要连接的服务器的地址,并选择网络协议(换句话说你是在选择要连接的端口)。该窗体另外还定义了两个属性,一个是port属性,另一个是RemoteHost属性,这两个属性用来接收你在文本框中输入的端口及服务器地址,并传递给Winsock控件。将下面的代码放在主窗体的“连接”按钮的Click事件中。
Private Sub cmdConnect_Click()
Dim frm As New frmConnect
frm.Show vbModal
If cmdConnect.Tag = "Connect" Then
If Not wsCommand.State = sckClosed Then
wsCommand.Close
Do Until wsCommand.State = sckClosed
DoEvents
Loop
End If
StatusBar.Caption = ""
wsCommand.Connect frm.RemoteHost, frm.Port
End If
End Sub
显示服务器的回应
当你按下“连接”按钮,可能会出现两种情况:一种是由于连接不成功而返回错误事件(你可在Winsock控件的帮助文件中查到这些错误事件);另一种是连接成功而返回一个Connect事件。如果连接成功,服务器会返回欢迎消息,从而触发DataArrival事件。下面的代码被放在该事件中:
Private Sub wsCommand_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
With StatusBar
.ForeColor = vbBlack
.Caption = "wsCommand : DataArrival ("& bytesTotal & " bytes)"
End With
lBytesRes = lBytesRes + bytesTotal
ToolBar.Caption = "Received: " & lBytesRes & " Sent: " & lBytesSent & " "
wsCommand.GetData strData
With txtCommand
.SetFocus
.Text = .Text & strData
.SelStart = Len(.Text)
End With
If Left(strData, 3) = "227" Then
MakeDataConnection strData
ElseIf Left(strData, 3) = "354" Then
bMailData = True
End If
End Sub
每次当Winsock控件从远程服务器接收到数据时都会触发DataArrival事件。通过Winsock的GetData方法,我们可以提取这些数据,并将这些数据放在变量strData中。然后我们将这些收到的数据放进文本框中。.SelStart = Len(.Text)语句的作用是使光标跳到文本框中文本的结束处。
输入命令
我只有一个文本框来接收你想要发送的命令,同时这个文本框还担负着显示由服务器传来的信息。那么程序如何知道它就将哪一行文本看作是你输入的命令而发送给服务器呢?本程序通过在文本框的KeyPress事件中建立一个“缓冲”的方法来实现。这个“缓冲”实际上是在Keypress事件中的静态变量,当你敲击键盘时,你所输入的字符就被储存在这个静态变量中,当你按下回车发送命令时,程序将该变量的值清空。下面是程序代码:
Private Sub txtCommand_KeyPress(KeyAscii As Integer)
Static strBuffer As String
On Error Resume Next
If KeyAscii = 8 Then 捕获BackSpace键
strBuffer = Left$(strBuffer, _ Len(strBuffer) - 1)
Else strBuffer = strBuffer & Chr$(KeyAscii)
End If
If KeyAscii = 13 Then 当按下回车键后发送命令。注意必须在命令后加上vbCrLf,否则服务器无法识别你所发出的命令
wsCommand.SendData strBuffer & vbCrLf
strBuffer = ""
End If
End Sub
如果你按了方向键,程序将忽略它们,下面的代码轻松地解决了这个问题。
Private Sub txtCommand_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode > 36 And KeyCode < 41 Then
KeyCode = 0
End If
End Sub
下面的代码使你在文本框中点击鼠标的动作无效,免得你到处乱输东西
Private Sub txtCommand_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
txtCommand.SelStart = Len(txtCommand.Text)
End Sub
断开与服务器的连接
如果你想关闭本程序或新建立一个连接,你必须断开当前的连接。为达到这一目的,你必须向服务器发送一个QUIT命令,或者调用Winsock的Close方法。同时有必要等待这一命令完成后再退出程序。通过Winsock的State属性,我们可以知道这一命令是否已经执行完毕。当Winsock的State属性等于sckClosed时,就表示socket已关闭了。这时就可以放心大胆地退出程序了。
Private Sub cmdClose_Click()
If Not wsCommand.State = sckClosed
Then wsCommand.Close
Do Until wsCommand.State = sckClosed
DoEvents
Loop
End If
Unload Me
End Sub
开发服务子程序
为了跟踪Winsock的事件,在每一个子程序中都有一小段代码,用来在状态栏中写入各种消息。这样我们就能迅速知道结果以及Winsock事件产生的原因。该控件只有7个事件,所以不需要花太多的时间来写这些代码。“另存为”按钮中的代码是用来保存整个过程的,请注意,文本框最多允许32K的数据。不过清除按钮,你可以清空整个文本框。