熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

Visual Basic.Net實現TCP協議

2013-11-13 10:17:52  來源: .NET編程 
TCP協議是TCP/IP協議簇中的傳輸層中的一個協議也是TCP/IP協議簇最為重要的協議之一在TCP/IP協議簇中有一個協議和TCP協議非常類似這就是UDP協議網絡上進行基於UDP協議的數據傳送時發送方只需知道接收方的IP地址(或主機名)和端口號就可以發送UDP數據包 而接收方只需知道發送方發送數據對應的端口號就能夠接收UDP數據包了傳送數據的雙方並不需要進行連接就能夠實現數據通訊這樣就導致基於UDP協議的網絡應用程序在傳送數據時無法保證可靠性完整性和安全性

   而TCP協議卻與之相反TCP協議是一種面向連接的並提供可靠的完整的安全的數據傳送的網絡協議它提供可靠字節服務的協議在網絡中通過TCP協議傳送數據之前發送方和接收方之間必須建立連接這種連接就是所謂的握手網絡中TCP應用如同日常生活中的打電話在通話之前首先要撥號震鈴(猶如發送方向接收方提出TCP連接申請並等待TCP連接申請通過)直到對方拿起電話時(發送方和接收方的TCP連接已經建立)就可以通話了(傳送數據)本文的主要內容就來介紹在Visual Basic Net實現基於TCP協議網絡數據傳送的一種簡單的方法

  一.簡介本文在實現TCP協議網絡應用時使用的類庫

  Net FrameWork SDK中提供了很多用以實現TCP協議或與之相關協議的類庫本文就選擇五個比較典型也是比較簡單的類加以介紹TcpListener類TcpClient類NetworkStream類StreamReader類和StreamWriter類TcpClient主要用以提出TCP連接申請TcpListener主要用以偵聽端口號並接收遠程主機的TCP連接申請NetworkStream類是實現TCP數據傳輸的基礎數據流StreamReader類作用是通過操作NetworkStream實現從網絡接收數據StreamWriter類作用是通過操作NetworkStream實現向網絡傳輸數據

   NetworkStream類

  NetworkStream類主要是提供用於網絡訪問的基礎數據流它主要是網絡數據傳輸的載體並提供同步異步方式來訪問網絡數據流雖然NetworkStream類有構造函數但在實際情況中更多是通過TcpClient實例的GetStream方法來初始化NetworkStream實例以下就是使用TcpClient實例的GetStream方法來初始化NetworkStream實例具體代碼

Dim tcpClient As TcpClient
Dim nsStream As NetworkStream
tcpClient = New TcpClient( )
對遠程主機的端口提出TCP連接申請
nsStream = tcpClientGetStream ( )
TCP連接建立後獲得網絡數據傳輸的基礎數據流
  在下面介紹的程序示例中就是利用NetworkStream作為傳送和接收數據的載體而操作這個載體的就是StreamWriter類和StreamReader類和表是NetworkStream類中一些常用的方法屬性及其說明

方法 說明 BeginRead 開始異步讀者基礎數據流 BeginWrite 開始異步寫入基礎數據流 Close 關閉流並可選擇關閉基礎套接字 EndRead 結束異步讀取 EndWrite 結束異步寫入 Flush 刷新流中的數據 Read 從流中讀取數據 Seek 將流的當前位置設置為給定值 SetLength 設置流的長度 Write 將數據寫入流
NetworkStream類中常用的方法及其說明

  其中BeginReadEndReadBeginWriteEndWrite是二對異步方法起作用分別相當於ReadWrite方法

屬性 說明 CanRead 獲取當前流是否支持讀取 CanSeek 獲取流是否支持查找該屬性總是返回 false CanWrite 獲取當前流是否支持寫入 DataAvailable 獲取是否可以在流上讀取數據 Length 流上可用數據的長度 Position 獲取或設置流中的當前位置

  表NetworkStream類中屬性及其說明

   StreamReader類

  StreamReader類能夠實現對基礎數據流的讀操作從而實現對經過基礎數據流傳送來的數據是StreamReader類的常用的方法及其說明

   方法 說明 Close 關閉StreamReader並釋放與閱讀器關聯的所有系統資源 DiscardBufferedData 允許StreamReader丟棄其當前數據 Peek 返回下一個可用的字符但不使用它 Read 讀取輸入流中的下一個字符或下一組字符 ReadBlock 從當前流中讀取最大數量的字符並從索引開始將該數據寫入緩沖區 ReadLine 從當前流中讀取一行字符並將數據作為字符串返回 ReadToEnd 從流的當前位置到末尾讀取流

  表NetworkStream類中常用的方法及其說明

   StreamWriter類

  StreamWriter類能夠實現對基礎數據流的寫操作從而實現提供基礎數據流來傳送數據是StreamWriter類的常用方法及其說明

   方法 說明 Close 關閉當前的StreamWriter和基礎流 Flush 清理當前編寫器的所有緩沖區並使所有緩沖數據寫入基礎流 Write 寫入基礎數據流 WriteLine 寫入重載參數指定的某些數據後跟行結束符

  表StreamWriter類的常用方法及其說明

  TcpClient 類

  TcpClient 類主要為TCP網絡服務提供客戶端連接TcpClient是類基於Socket類構建
它以更高的抽象程度提供TCP服務TcpClient 提供了通過網絡連接發送和接收數據的簡單方法和表分別是TcpClient類常用方法屬性及其說明


   方法 說明 Close 關閉 TCP 連接 Connect 使用指定的主機名和端口號將客戶端連接到 TCP主機 GetStream 返回用於發送和接收數據的流

  表TcpClient類常用的方法

   屬性 描述 LingerState 有關套接字逗留時間的信息 NoDelay 一個值該值在發送或接收緩沖區未滿時啟用延遲 ReceiveBufferSize 接收緩沖區的大小 ReceiveTimeout TcpClient在啟動後為接收數據而等待的時間長度 SendBufferSize 發送緩沖區的大小 SendTimeout 在您啟動發送操作後TcpClient將為接收確認而等待的時間長度

  表TcpClient類常用的屬性

  TcpListener 類

  TcpListener類的主要作用是從TCP網絡客戶端偵聽連接TcpListener類基於Socket 類
提供更高理念級別的TCP服務可以使用TcpListener從TCP客戶端偵聽連接像 FTP 和 HTTP 這樣的應用層協議是在 TcpListener 類的基礎上建立的和表分別是TcpListener類常用方法屬性及其說明

   方法 說明 AcceptSocket 接受掛起的連接請求 AcceptTcpClient 接受掛起的連接請求 Pending 確定是否有掛起的連接請求 Start 開始偵聽網絡請求 Stop 關閉偵聽器

  表TcpListener 類常用的方法

   屬性 說明 LocalEndpoint 獲取當前TcpListener的基礎EndPoint Active 獲取一個值該值指示 TcpListener 是否正主動偵聽客戶端連接 Server 獲取基礎網絡Socket

  表TcpListener 類常用的屬性

  二.Visual Basic Net實現基於TCP協議數據傳送程序的體系結構

  在下面介紹的用Visual Basic Net實現基於TCP協議的數據傳送程序是由二個子程序組成的也可以看成是服務器端程序和客戶端程序其中服務器端程序的功能是偵聽端口號接收遠程主要的TCP連接申請並接收遠程主機傳送來的文字數據另外一個子程序也就是所謂的客戶端程序主要實現向網絡的遠程主機提出TCP連接申請並在連接申請通過後向遠程主機傳送文字數據下面來詳細介紹Visual Basic Net實現TCP協議網絡數據傳送的服務器端程序和客戶端程序的具體步驟

  三.服務器端程序的具體實現步驟

  服務器端程序的實現關鍵在於偵聽端口號接收遠程主機的TCP連接申請獲得網絡數據傳輸的基礎數據流並通過基礎數據流接收數據接收數據使用的是StreamReader中ReadLine方法由於ReadLine方法是一個阻塞式的方法所以在下面具體的實現步驟中是接收數據是在創建的線程中完成的具體可參閱下面實現步驟中的第十一和十二步以下是Visual Basic Net實現TCP協議客戶端程序實現的具體步驟

   啟動Visual Studio Net

   選擇菜單【文件】|【新建】|【項目】後彈出【新建項目】對話框

   將【項目類型】設置為【Visual Basic項目】

   將【模板】設置為【Windows應用程序】

   在【名稱】文本框中輸入【服務器端程序】

   在【位置】的文本框中輸入【E:\VSNET項目】然後單擊【確定】按鈕這樣在E:\VSNET項目目錄中就產生了名稱為服務器端程序的文件夾並在裡面創建了名稱為服務器端程序的項目文件

   把Visual Studio Net的當前窗口切換到【Formvb(設計)】窗口並從【工具箱】中的【Windows窗體組件】選項卡中往Form窗體中拖入下列組件並執行相應的操作

  一個Label組件
  一個StatusBar組件
  一個ListBox組件
  一個Button組件並在這個Button組件拖入Form的設計窗體後雙擊它則系統會在Formvb文件分別產生這個組件的Click事件對應的處理代碼

   按照表所示調整窗體中各組件屬性的數值

   組件類型 組件名稱 屬性 設置結果 Form Form Text 服務器端程序 Form MaximizeBox False Form FormBorderStyle FixedSingle Button Button Text 啟動服務   Button FlatStyle Flat Label Label Text 服務尚未啟動 StatusBar StatusBar Text 無連接!

  表【服務器端程序】項目中組件設定數值表



   把Visual Studio Net的當前窗口切換到Formvb的代碼編輯窗口並在Formvb文件的最前面添加下列代碼下列代碼在Formvb中導入程序中要使用的類所在的命名空間


   Imports SystemNetSockets
使用到TcpListen類
Imports SystemThreading
使用到線程
Imports SystemIO
使用到StreamReader類

   在Formvb中創建各種可視組件的代碼中添加下列代碼下列代碼的作用是創建全局使用的實例和變量

   Private iPort As Integer =
定義偵聽端口號
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

   在Formvb中的InitializeComponent過程之後添加下列代碼下列代碼的作用是定義Listen過程此過程的作用是偵聽本地機的端口號接受網絡主機的TCP連接申請並接收從建立申請的遠程主機發送來的文本數據

   Private Sub Listen ( )
Try
 tlTcpListen = New TcpListener ( iPort )
 端口號來初始化TcpListener實例
 tlTcpListenStart ( )
 開始監聽
 StatusBarText = 正在監聽
 tcClient = tlTcpListenAcceptTcpClient ( )
 通過TCP連接請求
 nsStream = tcClientGetStream ( )
 獲取用以發送接收數據的網絡基礎數據流
 srRead = New StreamReader ( nsStream )
 以得到的網絡基礎數據流來初始化StreamReader實例
 StatusBarText = 已經建立TCP連接!
 循環偵聽
 While blistener
  Dim sMessage As String = srReadReadLine ( )
  從網絡基礎數據流中讀取一行數據
  If ( sMessage = STOP ) Then
   tlTcpListenStop ( )
   關閉偵聽
   nsStreamClose ( )
   srReadClose ( )
   釋放資源
   StatusBarText = 無連接!
   thThreadReadAbort ( )
   中止線程
   Return
  Else
   判斷是否為斷開TCP連接控制碼
   Dim sTime As String = DateTimeNowToShortTimeString ( )
   獲取接收數據時的時間
   ListBoxItemsAdd ( sTime + + sMessage )
  End If
 End While
Catch ex As SystemSecuritySecurityException
 MessageBoxShow ( 偵聽失敗! 錯誤 )
End Try
End Sub

   用下列代碼替換Formvb中的Button的Click事件對應的處理代碼下列代碼功能是用上面定義的Listen過程來初始化並啟動線程接收建立TCP連接的遠程主機發送來的文本數據

   Private Sub Button_Click ( ByVal sender As SystemObject ByVal e As SystemEventArgs ) Handles ButtonClick
 thThreadRead = New Thread ( New ThreadStart ( AddressOf Listen ) )
 以Listen過程來初始化線程實例
 thThreadReadStart ( )
 啟動線程
 ButtonEnabled = False
 LabelText = 服務已經啟動!
 LabelForeColor = ColorRed
End Sub

   用下列代碼替換Formvb中的Dispose過程下面代碼的作用是重新定義Dispose過程在Dispose過程手動清除使用的資源回收垃圾


   Protected Overloads Overrides Sub Dispose ( ByVal disposing As Boolean )
 Try
  thThreadReadAbort ( ) 中止線程
  tlTcpListenStop ( ) 關閉偵聽
  tcClientClose ( )
  nsStreamClose ( )
  srReadClose ( ) 釋放資源
 Catch
 End Try
 If disposing Then
  If Not ( components Is Nothing ) Then
   componentsDispose ( )
  End If
 End If
 MyBaseDispose ( disposing )
End Sub

   至此在上述步驟都正確執行後【服務器端程序】項目的全部工作就完成了編譯生成可執行文件後接著介紹客戶端程序的實現步驟

  四.客戶端端程序的具體實現步驟

  客戶端端序的實現關鍵在於向網絡中的遠程主機提出TCP連接申請並在申請通過後得到傳輸數據的基礎數據流並通過對基礎數據流進行寫操作向遠程主機傳送文本數據

  由於在客戶端程序中沒有使用阻塞式的方法所以程序中沒有使用到線程對遠程主機提出TCP連接申請的具體實現方法請參閱以下第步對基礎數據流進行寫操作從而實現向遠程主機傳送文本數據的方法請參閱以下第步下面客戶端程序的具體實現步驟

   啟動Visual Studio Net

   選擇菜單【文件】|【新建】|【項目】後彈出【新建項目】對話框

   將【項目類型】設置為【Visual Basic項目】

   將【模板】設置為【Windows應用程序】

   在【名稱】文本框中輸入【客戶端程序】

   在【位置】的文本框中輸入【E:\VSNET項目】然後單擊【確定】按鈕這樣在E:\VSNET項目目錄中就產生了名稱為客戶端程序的文件夾並在裡面創建了名稱為客戶端程序的項目文件

   把Visual Studio Net的當前窗口切換到【Formvb(設計)】窗口並從【工具箱】中的【Windows窗體組件】選項卡中往Form窗體中拖入下列組件並執行相應的操作

  二個Label組件
  二個TextBox組件
  一個StatusBar組件
  二個Button組件並在這二個Button組件拖入Form的設計窗體後雙擊它們則系統會在Formvb文件分別產生這二個組件的Click事件對應的處理代碼

   按照表所示調整窗體中各組件屬性的數值

   組件類型 組件名稱 屬性 設置結果 Form Form Text 客戶端程序 Form MaximizeBox False Form FormBorderStyle FixedSingle Button Button Text 連接 Button FlatStyle Flat Button Text 發送 Button FlatStyle Flat Label Label Text 服務器IP地址 Label Text 信息 StatusBar StatusBar Text 無連接! TextBox TextBox Text TextBox BorderStyle FixedSingle TextBox Text TextBox BorderStyle FixedSingle

  表【客戶端程序】項目中組件設定數值表

   把Visual Studio Net的當前窗口切換到Formvb的代碼編輯窗口並在Formvb文件的最前面添加下列代碼下列代碼在Formvb中導入程序中要使用的類所在的命名空間

   Imports SystemNetSockets
使用到TcpListen類
Imports SystemIO
使用到StreamWriter類
Imports SystemNet
使用IPAddress類IPHostEntry類等

   在Formvb中創建各種可視組件的代碼中添加下列代碼下列代碼的作用是創建全局使用的實例和變量

   Private swWriter As StreamWriter
 用以向網絡基礎數據流傳送數據
 Private nsStream As NetworkStream
 創建發送數據的網絡基礎數據流
 Private tcpClient As TcpClient
 通過它實現向遠程主機提出TCP連接申請
 Private tcpConnect As Boolean = False
 定義標識符用以表示TCP連接是否建立

   用下列代碼替換Formvb中的Button的Click事件對應的處理代碼下列代碼功能是向遠程主機的端口號提出TCP連接申請並在連接建立後初始化基礎數據流


   Private Sub Button_Click ( ByVal sender As SystemObject ByVal e As SystemEventArgs ) Handles ButtonClick
 Dim ipRemote As IPAddress
 Dim sHostName As String
 Dim tcpClient As TcpClient
 Try
  ipRemote = IPAddressParse ( TextBoxText )
 Catch
  MessageBoxShow ( 輸入的IP地址不合法! 錯誤提示! )
  Return
  判斷給定的IP地址的合法性
 End Try
 Try
  tcpClient = New TcpClient ( TextBoxText )
  對遠程主機的端口提出TCP連接申請
  nsStream = tcpClientGetStream ( )
  通過申請並獲取傳送數據的網絡基礎數據流
  swWriter = New StreamWriter ( nsStream )
  使用獲取的網絡基礎數據流來初始化StreamWriter實例
  ButtonEnabled = False
  ButtonEnabled = True
  tcpConnect = True
  StatusBarText = 已經連接!
 Catch
  MessageBoxShow ( 無法和遠程主機端口建立連接! 錯誤提示! )
  Return
 End Try
End Sub

   用下列代碼替換Formvb中的Button的Click事件對應的處理代碼下列代碼功能是對基礎數據流進行寫操作實現向遠程主機傳輸文本數據

   Private Sub Button_Click ( ByVal sender As SystemObject ByVal e As SystemEventArgs ) Handles ButtonClick
 If ( TextBoxText <> ) Then
  swWriterWriteLine ( TextBoxText )
  刷新當前數據流中的數據
  swWriterFlush ( )
  TextBoxText =
 Else
  MessageBoxShow ( 發送信息不能為空! 錯誤提示! )
 End If
End Sub

   用下列代碼替換Formvb中的Dispose過程下面代碼的作用是重新定義Dispose過程在過程中判斷TCP連接是否仍然建立如果建立則向遠程主機傳送控制碼斷開連接並手動清除使用的資源回收垃圾

   Protected Overloads Overrides Sub Dispose ( ByVal disposing As Boolean )
 If tcpConnect Then
  swWriterWriteLine ( STOP )
  發送控制碼
  swWriterFlush ( )
  刷新當前數據流中的數據
  nsStreamClose ( )
  swWriterClose ( )
  清除資源 ( )
 End If
 If disposing Then
  If Not ( components Is Nothing ) Then
   componentsDispose ( )
  End If
 End If
 MyBaseDispose ( disposing )
End Sub

   至此【客戶端程序】就完成了在正確編譯項目後就可以選擇局域網中任二台計算機來測試了一台運行客戶端程序一台運行服務器端程序在服務器端程序運行後單擊【啟動服務】按鈕啟動服務後在客戶端程序的【服務器IP地址】文本框中輸入網絡中運行服務器端程序主機對應的IP地址後單擊【連接】按鈕就和啟動服務的服務器端程序建立TCP連接此時就可以在客戶端程序的【信息】文本框中輸入文本信息後單擊【發送】按鈕就能夠把文本信息傳送到服務器端了和圖分別是客戶端程序和服務器端程序運行後進行通訊時的界面

  五.總結

  雖然本文用Visual Basic Net實現一個簡單的基於TCP協議的網絡應用程序但程序中使用的是NetworkStream作為載體通過StreamWriter和StreamReader通過操作這個載體從而實現數據傳輸和接收這種實現TCP協議方法雖然比較簡單但卻無法回避NetworkStream作為網絡傳輸接收數據載體的一個致命的缺陷那就是NetworkStream只能傳輸基於文本類型的數據如果要傳輸基於字節的數據使用這種方法就勉為其難了而套接字(Socket)就能夠勝任這項工作套接字不僅能夠實現各種類型數據在網絡上的傳輸和接收也是實現網絡中其他應用協議的關鍵諸位若想真正成為網絡編程的高手必須掌握Socket的使用方法最後希望本文能夠開啟您編寫網絡應用程序之門對您掌握更深層次網絡編程有所幫助


From:http://tw.wingwit.com/Article/program/net/201311/13184.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.