DotNet · 2007年12月9日

Visual Basic .Net实现基于TCP协议数据传送程序的体系结构:

Visual Basic
.Net实现基于TCP协议数据传送程序的体系结构:
 在下面介绍的用Visual Basic
.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 无连接!
表05:【服务器端程序】项目中组件设定数值表

  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

12.
用下列代码替换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 
  14. 至此在上述步骤都正确执行后,【服务器端程序】项目的全部工作就完成了。编译、生成可执行文件后,接着介绍客户端程序的实现步骤。
四.客户端端程序的具体实现步骤:

  客户端端序的实现关键在于向网络中的远程主机提出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
表06:【客户端程序】项目中组件设定数值表
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的使用方法。最后希望本文能够开启您编写网络应用程序之门,对您掌握更深层次网络编程有所帮助。

最新电影,电视剧,尽在午夜剧场

电影电视剧午夜不寂寞