第三章 資料的傳收與接送

Post on 03-Jan-2016

52 views 0 download

description

第三章 資料的傳收與接送. 3-1 TCP 程式設計 3-2 UDP 程式設計 3-3 Socket 程式設計 3-4 資料的非同步傳送與接收. 第三章 資料的傳收與接送. 3-1 TCP 程式設計. TCP/IP 網路程式的架構. 建立伺服端與接收資料. ' 建立 TcpListener 類別 TcpListener = New TcpListener (IPAddress 類別 , 通訊埠 ) MyTcpListener.Start() ' 接受客戶端的 TcpClient 服務 - PowerPoint PPT Presentation

Transcript of 第三章 資料的傳收與接送

第三章 資料的傳收與接送 3-1 TCP程式設計 3-2 UDP程式設計 3-3 Socket程式設計 3-4資料的非同步傳送與接收

3-1 TCP 程式設計第三章 資料的傳收與接送

TCP/IP 網路程式的架構

建立伺服端與接收資料' 建立 TcpListener 類別 TcpListener = New TcpListener (IPAddress 類別 , 通訊埠 )MyTcpListener.Start()' 接受客戶端的 TcpClient 服務Dim TcpClient As TcpClient = MyTcpListener.AcceptTcpClient()' 取得來自客戶端的 IP AddressDim clientIP As IPAddress = IPAddress.Parse( CType(MyTcpListener.LocalEndpoint, _ IPEndPoint).Address.ToString())' 取得客戶端的 TcpClient 所傳送的資料Dim ns As NetworkStream = MyTcpClient.GetStreamDim data(MyTcpClient.ReceiveBufferSize) As Byte' 讀入傳進的資料的長度Dim BytesRead As Integer = ns.Read(data, 0 , CInt( MyTcpClient.ReceiveBufferSize))' 將 Byte 型態轉換為 String接收資料 =Encoding.Default.GetString(data, 0, BytesRead))

連接至伺服端與傳送資料' 連接至伺服端TcpClient.Connect(IP 位址 , 通訊埠 ) ' 使用 NetworkStream 類別來接收與傳送資料 Dim ns As NetworkStream = TcpClient.GetStream ' 使用預設的編碼方式來將傳送資料編碼 Dim data As Byte() = Encoding.Default.GetBytes

( 要傳送的資料封包 ) ' 傳送資料 ns.Write(data, 0, data.Length)

SocketException 類別 SocketErrorCode :

說明屬於哪一種型態的錯誤,讓程式設計師來判斷發生錯誤的原因,並做進一步的處理。

僅陳述當時網路環境的狀況,並不全然是程式所造成的錯誤。

Encoding 類別 替資料流位元組進行編碼 純英文可用ASCII方式編碼 欲顯示中文可採用Default方式編碼

ASCII 取得 ASCII字元集的編碼方式。BigEndianUnicode 取得 UTF-16格式的編碼方式,它是以位元組由大

到小位元組順序來排列。Default 取得目前作業系統的編碼方式。Unicode 取得 UTF-16格式的編碼方式,它是以位元組由小

到大位元組順序來排列。UTF32 取得 UTF-32格式的編碼方式,它是以位元組由小

到大位元組順序來排列。UTF7 取得 UTF-7格式的編碼方式。UTF8 取得 UTF-8格式的編碼方式。

Thread( 執行緒 )

宣告 Thread 物件 (eg. 程式 3-1-1) Dim tcpThread As Thread

產生 Thread 物件 tcpThread = New Thread(New

ThreadStart(AddressOf StartTcpListener)) 啟動 Thread 物件

tcpThread.Start( ) Thread 副程式名稱

Public Sub StartTcpListener( )

NetworkStream :非同步讀取資料

BeginRead 方法。TcpClient.GetStream.BeginRead( 接收的資料 ,

開始讀取位置 , 讀取長度 , AddressOf 指派程序 , Nothing)

clientTCP.GetStream.BeginRead( data, 0, _

CInt(clientTCP.ReceiveBufferSize), _

AddressOf ReceiveMessage, Nothing)

會在 BeginRead 完成時加以執行

NetworkStream :停止非同步讀取

EndRead 方法。資料長度=TcpClientTCP.GetStream.EndRead( IAsyncResult)

讀取資料 =Encoding.Default.GetString( 接收資料 , 開始位置 , 資料長度 )

範例 : 3-1-4

放入本身 read callback function 所傳入之 參

NetworkStream 程式碼範例 使用指派者執行緒 ( 上一層 ) 的 Subroutine ( 範例 : 3-1-4)

Me.Invoke(New 指派程序宣告名稱 (AddressOf Me.程序名稱 ), 參數 )

 ' 指派程序宣告Public Delegate Sub 指派程序宣告名稱 ( 參數 )

 Public Sub 程序名稱 ( 參數 )

' 要處理的事End Sub

3-2 UDP 程式設計第三章 資料的傳收與接送

UdpClient 類別 定義在 System.Net.Sockets 的命名空間。 為一個不可靠的傳輸協定:

傳送資料後,並不會去確認對方是否有收到完整的資料。

接收資料的客戶端,也不會去考慮所收到的資料是否正確?完整?重覆接收?

建立 UdpClient 類別' 僅初始化 UdpClientDim udpClient As New UdpClient()' 連接至本機通訊埠Dim udpClient As New UdpClient( 通訊埠 )' 連接至本機Dim udpClient As New UdpClient(AddressFamily 家族 )' 連接至指定 IP 與通訊埠Dim udpClient As New UdpClient(IPEndPoint 類別 )' 連接至本機通訊埠Dim udpClient As New UdpClient( 通訊埠 , AddressFamily 家族 )' 連接至指定主機名稱與通訊埠Dim udpClient As New UdpClient( 主機名稱 , 通訊埠 )

UdpClient 連接至伺服器

' 連接至指定 IP 與通訊埠UdpClient.Connect(IPEndPoint 類別 )

' 連接至指定 IP 與通訊埠UdpClient.Connect(IPAddress 類別 , 通訊埠 )

' 連接至指定主機名稱與通訊埠UdpClient.Connect( 主機名稱 , 通訊埠 )

UdpClient 傳送資料至伺服器

' 已連接至伺服器UdpClient.Send( 傳送資料位元組陣列 , 傳送資

料的長度 )' 尚未連接至伺服器UdpClient.Send( 傳送資料位元組陣列 , 傳送資

料的長度 , IPEndPoint 類別 )' 尚未連接至伺服器UdpClient.Send( 傳送資料位元組陣列 , 傳送資

料的長度 , 主機名稱 , 通訊埠 )

UdpClient 接收伺服器的資料

UdpClient.Receive( 伺服器的 IPEndPoint 類別 )

關閉 UdpClient 通訊UdpClient.Close()

接收端與發送端的通訊埠與 IP 位址

3-3 SOCKET 程式設計第三章 資料的傳收與接送

Socket 應用程式的架構

Socket 程式的作業流程

Socket

命名空間: System.Net.Sockets Socket 類別針對網路通訊提供了一系列豐

富的方法和屬性 Socket 類別可以讓您使用 ProtocolType 列

舉型別中列出的任何通訊協定來執行同步的和非同步的 (Asynchronous) 資料傳送。

Socket

Socket 類別遵循 .NET Framework 的非同步方法命名模式。例如,同步 Receive 方法對應於非同步 BeginReceive 和 EndReceive 方法。

如果您正在撰寫相當簡單的應用程式,而且不需要最大效能,請考慮使用 TcpClient、 TcpListener 和 UdpClient 。這些類別會提供 Socket 通訊較為簡單且更易於使用的介面

同步作業模式 --TCP

伺服器可以使用 Listen 方法來聆聽連接 Accept 方法會處理任何輸入的連接要求,

並傳回可以用來與遠端主機進行資料傳遞的 Socket

使用這個傳回的 Socket 來呼叫 Send 或 Receive 方法

如果您要指定本機 IP 位址和通訊埠編號,請在呼叫 Listen 方法之前呼叫 Bind 方法

同步作業模式 --TCP

如果您要基礎服務提供者為您指派可用的通訊埠,請使用編號為零的通訊埠

如果您要連接至接聽主機,請呼叫 Connect 方法。 若要進行資料傳遞,請呼叫 Send 或 Receive 方法。

同步作業模式 --UDP

不需要聆聽連接 呼叫 ReceiveFrom 方法以接受任何輸入的

資料包 (Datagram) 使用 SendTo 方法以傳送資料包至遠端主

建立 Socket 類別

DIM SocketServer AS New Socket( 通訊協定家族 , 通訊端類型 , 通訊協定 )

DIM SocketServer AS = New Socket( _

AddressFamily.InterNetwork, _

SocketType.Stream, ProtocolType.Tcp)

將 IP 位址、通訊埠與 Socket 物件繫結

Dim ep As New IPEndPoint(IPAddress.Parse(IP 位址 ), 通訊埠 )

SocketServer.Bind(ep)

Dim ep As New IPEndPoint( IPAddress.Parse("127.0.0.1"), 5001)

SocketServer.Bind(ep)

開啟 Socket 物件的接聽功能

SocketServer.Listen( 最大連接數 )

SocketServer. Listen(9)

建立客戶端 Socket 物件DIM SocketClient AS New Socket( 通訊協定家族 , 通訊端

類型 , 通訊協定 )Dim ep As New IPEndPoint(IPAddress.Parse(IP 位址 ), 通

訊埠 )SocketClient.Connect(ep) DIM SocketClient AS New

Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)Dim ep As New IPEndPoint(IPAddress.Parse("127.0.0.1"),

5001)SocketClient.Connect(ep)

伺服端 Socket 接受客戶端 Socket連接

Dim SocketClient As Socket

SocketClient = SocketServer.Accept()

Socket 類別傳送資料

SocketClient.Send(Encoding.Default.GetBytes(" 傳送資料 "))

Socket 類別接收資料

Dim RecvLength As Integer

Dim RecvStr As String

RecvLength = SocketClient.Receive(data)

If RecvLength > 0 Then

RecvStr = Encoding.Default.GetString(data).Trim

End If

關閉已開啟的 Socket 通訊

SocketServer.Close 暫停通訊

Shutdown

Receive 暫停接收資料。Send 暫停傳送資料。Both 暫停接收和傳送資料。

3-4 資料的非同步傳送與接收第三章 資料的傳收與接送

非同步作業模式 --TCP

使用 Socket 、 BeginConnect 和 EndConnect 方法來與接聽主機進行連接

使用 BeginSend 和 EndSend , BeginReceive 和 EndReceive 方法,以非同步方式進行資料傳遞

輸入的連接要求可以使用 BeginAccept 和 EndAccept 加以處理

非同步作業模式 --UDP

使用 BeginSendTo 和 EndSendTo 傳送資料包

使用 BeginReceiveFrom 和 EndReceiveFrom 接收資料包

非同步作業模式 如果在一個通訊端上執行多個非同步的作

業,這些作業不一定會依照所啟動的順序完成

完成傳送和接收資料時,請使用 Shutdown 方法來停用 Socket

呼叫 Shutdown 之後,要呼叫 Close 方法來釋放與 Socket 相關的所有資源。

Socket 類別非同步接受連接' 建立委派Accept = New AsyncCallback(AddressOf

OnAccept)' 開始準備接收客戶端 Socket 連接SocketServer.BeginAccept(Accept, SocketServer) Public Sub OnAccept(ByVal ar As IAsyncResult) ' 接受客戶端連入 SocketClient = SocketServer.EndAccept(ar)End Sub

Socket 類別非同步接收資料' 建立委派ReceiveData = New AsyncCallback(AddressOf OnReceive)' 開始接受客戶端 Socket 傳送資料SocketClient.BeginReceive(data, 0, data.Length, SocketFlags.None, _ ReceiveData, SocketClient) Public Sub OnReceive(ByVal ar As IAsyncResult) ' 完成接收資料 recvLength = AcceptClient.EndReceive(ar) '繼續開始接收資料 SocketClient.BeginReceive( data, 0, data.Length, SocketFlags.None

, _ ReceiveData, SocketClient)End Sub

Socket 類別非同步傳送資料' 建立委派SendData = New AsyncCallback(AddressOf OnSend)' 開始傳送資料SocketClient.BeginSend(byteSend, 0, byteSend.Length,

_ SocketFlags.None, SendData, SocketClient) Public Sub OnSend(ByVal ar As IAsyncResult) ' 結束傳送資料 SocketClient.EndSend(ar)End Sub

客戶端 Socket 非同步連接至伺服端 Socket

' 建立委派Connect = New AsyncCallback(AddressOf OnConnect)' 開始連接至 Socket 伺服端SocketClient.BeginConnect(IPEndPoint, Connect,

SocketClient) Public Sub OnConnect(ByVal ar As IAsyncResult) ' 結束連接至 Socket 伺服端 SocketClient.EndConnect(ar)End Sub