Visual Basic .Net实现基于TCP协议数据传送程序的体系结构:
.Net实现基于TCP协议数据传送程序的体系结构:
.Net实现基于TCP协议的数据传送程序是由二个子程序组成的。也可以看成是服务器端程序和客户端程序,其中:服务器端程序的功能是侦听端口号,接收远程主要的TCP连接申请,并接收远程主机传送来的文字数据。另外一个子程序,也就是所谓的客户端程序,主要实现向网络的远程主机提出TCP连接申请,并在连接申请通过后,向远程主机传送文字数据。下面来详细介绍Visual
Basic
.Net实现TCP协议网络数据传送的服务器端程序和客户端程序的具体步骤。
三.服务器端程序的具体实现步骤:
服务器端程序的实现关键在于侦听端口号,接收远程主机的TCP连接申请,获得网络数据传输的基础数据流,并通过基础数据流接收数据。接收数据使用的是
StreamReader中ReadLine方法,由于ReadLine方法是一个阻塞式的方法,所以在下面具体的实现步骤中,是接收数据是在创建的线程中完成的,具体可参阅下面实现步骤中的第十一和十二步。以下是Visual
Basic .Net实现TCP协议客户端程序实现的具体步骤:
1. 启动Visual Studio .Net。
2.
选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。
3. 将【项目类型】设置为【Visual
Basic项目】。
4. 将【模板】设置为【Windows应用程序】。
5.
在【名称】文本框中输入【服务器端程序】。
6.
在【位置】的文本框中输入【E:\VS.NET项目】,然后单击【确定】按钮,这样在”E:\VS.NET项目”目录中就产生了名称为”服务器端程序”的文件夹,并在里面创建了名称为”服务器端程序”的项目文件。
7.
把Visual Studio
.Net的当前窗口切换到【Form1.vb(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应的操作:
一个Label组件。
一个StatusBar组件。
一个ListBox组件。
一个Button组件,并在这个Button组件拖入Form1的设计窗体后,双击它,则系统会在Form1.vb文件分别产生这个组件的Click事件对应的处理代码。
8.
按照表05所示调整窗体中各组件属性的数值:
组件类型 | 组件名称 | 属性 | 设置结果 |
Form | Form1 | Text | 服务器端程序 |
Form1 | MaximizeBox | False | |
Form1 | FormBorderStyle | FixedSingle | |
Button | Button1 | Text | 启动服务 |
Button1 | FlatStyle | Flat | |
Label | Label1 | Text | 服务尚未启动 |
StatusBar | StatusBar1 | Text | 无连接! |
9. 把Visual Studio
.Net的当前窗口切换到Form1.vb的代码编辑窗口,并在Form1.vb文件的最前面添加下列代码,下列代码在Form1.vb中导入程序中要使用的类所在的命名空间:
Imports System.Net.Sockets ‘使用到TcpListen类 Imports System.Threading ‘使用到线程 Imports System.IO ‘使用到StreamReader类 |
10.
在Form1.vb中创建各种可视组件的代码中添加下列代码,下列代码的作用是创建全局使用的实例和变量:
Private iPort As Integer = 8000 '定义侦听端口号 Private thThreadRead As Thread '创建线程,用以侦听端口号,接收信息 Private tlTcpListen As TcpListener '侦听端口号 Private blistener As Boolean = True '设定标示位,判断侦听状态 Private nsStream As NetworkStream '创建接收的基本数据流 Private srRead As StreamReader '从网络基础数据流中读取数据 Private tcClient As TcpClient
11.
在Form1.vb中的InitializeComponent过程之后添加下列代码,下列代码的作用是定义Listen过程,此过程的作用是侦听本地机的8000端口号,接受网络主机的TCP连接申请,并接收从建立申请的远程主机发送来的文本数据:
Private Sub Listen ( ) Try tlTcpListen = New TcpListener ( iPort ) '以8000端口号来初始化TcpListener实例 tlTcpListen.Start ( ) '开始监听 StatusBar1.Text = "正在监听..." tcClient = tlTcpListen.AcceptTcpClient ( ) '通过TCP连接请求 nsStream = tcClient.GetStream ( ) '获取用以发送、接收数据的网络基础数据流 srRead = New StreamReader ( nsStream ) '以得到的网络基础数据流来初始化StreamReader实例 StatusBar1.Text = "已经建立TCP连接!" '循环侦听 While blistener Dim sMessage As String = srRead.ReadLine ( ) '从网络基础数据流中读取一行数据 If ( sMessage = "STOP" ) Then tlTcpListen.Stop ( ) '关闭侦听 nsStream.Close ( ) srRead.Close ( ) '释放资源 StatusBar1.Text = "无连接!" thThreadRead.Abort ( ) '中止线程 Return Else '判断是否为断开TCP连接控制码 Dim sTime As String = DateTime.Now.ToShortTimeString ( ) '获取接收数据时的时间 ListBox1.Items.Add ( sTime + " " + sMessage ) End If End While Catch ex As System.Security.SecurityException MessageBox.Show ( "侦听失败!" , "错误" ) End Try End Sub |
用下列代码替换Form1.vb中的Button1的Click事件对应的处理代码,下列代码功能是用上面定义的Listen过程来初始化并启动线程,接收建立TCP连接的远程主机发送来的文本数据:
Private Sub Button1_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles Button1.Click thThreadRead = New Thread ( New ThreadStart ( AddressOf Listen ) ) '以Listen过程来初始化线程实例 thThreadRead.Start ( ) '启动线程 Button1.Enabled = False Label1.Text = "服务已经启动!" Label1.ForeColor = Color.Red End Sub
13.
用下列代码替换Form1.vb中的Dispose过程,下面代码的作用是重新定义Dispose过程,在Dispose过程手动清除使用的资源,回收垃圾:
Protected Overloads Overrides Sub Dispose ( ByVal disposing As Boolean ) Try thThreadRead.Abort ( ) '中止线程 tlTcpListen.Stop ( ) '关闭侦听 tcClient.Close ( ) nsStream.Close ( ) srRead.Close ( ) '释放资源 Catch End Try If disposing Then If Not ( components Is Nothing ) Then components.Dispose ( ) End If End If MyBase.Dispose ( disposing ) End Sub
四.客户端端程序的具体实现步骤:
客户端端序的实现关键在于向网络中的远程主机提出TCP连接申请,并在申请通过后,得到传输数据的基础数据流,并通过对基础数据流进行写操作向远程主机传送文本数据。由于在客户端程序中没有使用阻塞式的方法,所以程序中没有使用到线程。对远程主机提出TCP连接申请的具体实现方法请参阅以下第步;对基础数据流进行写操作,从而实现向远程主机传送文本数据的方法请参阅以下第步。下面客户端程序的具体实现步骤:
1.
启动Visual Studio .Net。
2. 选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。
3.
将【项目类型】设置为【Visual Basic项目】。
4. 将【模板】设置为【Windows应用程序】。
5.
在【名称】文本框中输入【客户端程序】。
6.
在【位置】的文本框中输入【E:\VS.NET项目】,然后单击【确定】按钮,这样在”E:\VS.NET项目”目录中就产生了名称为”客户端程序”的文件夹,并在里面创建了名称为”客户端程序”的项目文件。
7.
把Visual Studio
.Net的当前窗口切换到【Form1.vb(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应的操作:
二个Label组件。
二个TextBox组件。
一个StatusBar组件。
二个Button组件,并在这二个Button组件拖入Form1的设计窗体后,双击它们,则系统会在Form1.vb文件分别产生这二个组件的Click事件对应的处理代码。
8.
按照表01所示调整窗体中各组件属性的数值:
组件类型 | 组件名称 | 属性 | 设置结果 |
Form | Form1 | Text | 客户端程序 |
Form1 | MaximizeBox | False | |
Form1 | FormBorderStyle | FixedSingle | |
Button | Button1 | Text | 连接 |
Button1 | FlatStyle | Flat | |
Button2 | Text | 发送 | |
Button2 | FlatStyle | Flat | |
Label | Label1 | Text | 服务器IP地址: |
Label2 | Text | 信息: | |
StatusBar | StatusBar1 | Text | 无连接! |
TextBox | TextBox1 | Text | “” |
TextBox1 | BorderStyle | FixedSingle | |
TextBox2 | Text | “” | |
TextBox2 | BorderStyle | FixedSingle |
9. 把Visual Studio
.Net的当前窗口切换到Form1.vb的代码编辑窗口,并在Form1.vb文件的最前面添加下列代码,下列代码在Form1.vb中导入程序中要使用的类所在的命名空间:
Imports System.Net.Sockets '使用到TcpListen类 Imports System.IO '使用到StreamWriter类 Imports System.Net '使用IPAddress类、IPHostEntry类等
10.
在Form1.vb中创建各种可视组件的代码中添加下列代码,下列代码的作用是创建全局使用的实例和变量:
Private swWriter As StreamWriter '用以向网络基础数据流传送数据 Private nsStream As NetworkStream '创建发送数据的网络基础数据流 Private tcpClient As TcpClient '通过它实现向远程主机提出TCP连接申请 Private tcpConnect As Boolean = False '定义标识符,用以表示TCP连接是否建立
11.
用下列代码替换Form1.vb中的Button1的Click事件对应的处理代码,下列代码功能是向远程主机的8000端口号提出TCP连接申请,并在连接建立后,初始化基础数据流:
Private Sub Button1_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles Button1.Click Dim ipRemote As IPAddress Dim sHostName As String Dim tcpClient As TcpClient Try ipRemote = IPAddress.Parse ( TextBox1.Text ) Catch MessageBox.Show ( "输入的IP地址不合法!" , "错误提示!" ) Return '判断给定的IP地址的合法性 End Try Try tcpClient = New TcpClient ( TextBox1.Text , 8000 ) '对远程主机的8000端口提出TCP连接申请 nsStream = tcpClient.GetStream ( ) '通过申请,并获取传送数据的网络基础数据流 swWriter = New StreamWriter ( nsStream ) '使用获取的网络基础数据流来初始化StreamWriter实例 Button1.Enabled = False Button2.Enabled = True tcpConnect = True StatusBar1.Text = "已经连接!" Catch MessageBox.Show ( "无法和远程主机8000端口建立连接!" , "错误提示!" ) Return End Try End Sub |
12.
用下列代码替换Form1.vb中的Button2的Click事件对应的处理代码,下列代码功能是对基础数据流进行写操作,实现向远程主机传输文本数据:
Private Sub Button2_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles Button2.Click If ( TextBox2.Text <> "" ) Then swWriter.WriteLine ( TextBox2.Text ) '刷新当前数据流中的数据 swWriter.Flush ( ) TextBox2.Text = "" Else MessageBox.Show ( "发送信息不能为空!" , "错误提示!" ) End If End Sub |
13.
用下列代码替换Form1.vb中的Dispose过程,下面代码的作用是重新定义Dispose过程,在过程中判断TCP连接是否仍然建立,如果建立则向远程主机传送控制码,断开连接,并手动清除使用的资源,回收垃圾:
Protected Overloads Overrides Sub Dispose ( ByVal disposing As Boolean ) If tcpConnect Then swWriter.WriteLine ( "STOP" ) '发送控制码 swWriter.Flush ( ) '刷新当前数据流中的数据 nsStream.Close ( ) swWriter.Close ( ) '清除资源 ( ) End If If disposing Then If Not ( components Is Nothing ) Then components.Dispose ( ) End If End If MyBase.Dispose ( disposing ) End Sub |
14.
至此【客户端程序】就完成了。在正确编译项目后。就可以选择局域网中任二台计算机来测试了,一台运行客户端程序,一台运行服务器端程序。在服务器端程序运行后,单击【启动服务】按钮,启动服务后。在客户端程序的【服务器IP地址】文本框中输入网络中运行服务器端程序主机对应的IP地址后,单击【连接】按钮,就和启动服务的服务器端程序建立TCP连接,此时就可以在客户端程序的【信息】文本框中输入文本信息后,单击【发送】按钮就能够把文本信息传送到服务器端了。图03和图04分别是客户端程序和服务器端程序运行后进行通讯时的界面:
五.总结:
虽然本文用Visual
Basic .Net实现一个简单的基于TCP协议的网络应用程序。但程序中使用的是NetworkStream作为载体,通过StreamWriter和
StreamReader通过操作这个载体从而实现数据传输和接收。这种实现TCP协议方法比较简单。而套接字(Socket)不仅能够实现各种类型数据在网络上的传输和接收,也是实现网络中其他应用协议的关键。诸位若想真正成为网络编程的高手,必须掌握Socket的使用方法。最后希望本文能够开启您编写网络应用程序之门,对您掌握更深层次网络编程有所帮助。