第3章 TCP編程_第1頁
第3章 TCP編程_第2頁
第3章 TCP編程_第3頁
第3章 TCP編程_第4頁
第3章 TCP編程_第5頁
已閱讀5頁,還剩47頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、3.1 TCP簡介簡介 3.2 同步與異步同步與異步 3.3 C#中的中的TCP編程類編程類 3.4 TCP基礎編程的一般步驟基礎編程的一般步驟 3.5 同步同步TCP編程編程 3.6 異步異步TCP編程編程 3.7 兩種兩種TCP程序的區(qū)別程序的區(qū)別 3.1.1 TCP的工作過程的工作過程 1. 連接的建立連接的建立 TCP協(xié)議通過三個報文段完成類似電話呼叫的連接建立過程,這個過程稱 為三次握手(three-way handshake),如圖3.1所示。 2. 傳輸數(shù)據(jù)傳輸數(shù)據(jù) 一旦通信雙方建立了TCP連接,連接中的任何一方都能向對方發(fā)送數(shù)據(jù)和接 收對方發(fā)來的數(shù)據(jù)。TCP協(xié)議負責把用戶數(shù)據(jù)(

2、字節(jié)流)按一定的格式和長度組 成多個數(shù)據(jù)報進行發(fā)送,并在接收到數(shù)據(jù)報之后按分解順序重新組裝和恢復用戶 數(shù)據(jù)。 利用TCP傳輸數(shù)據(jù)時,數(shù)據(jù)是以字節(jié)流的形式進行傳輸?shù)摹?3. 連接的終止連接的終止 建立一個連接需要三次握手,而終止一個連接要經(jīng)過四次握手,這是由 TCP的半關閉(half-close)造成的。具體過程如圖3.2所示。 TCP最主要的特點如下。 (1)是面向連接的協(xié)議。 (2)端到端的通信。每個TCP連接只能有兩個端點,而且只能一對一通信, 不能一點對多點直接通信。 (3)高可靠性。通過TCP連接傳送的數(shù)據(jù),能保證數(shù)據(jù)無差錯、不丟失、 不重復地準確到達接收方,并且保證各數(shù)據(jù)到達的順序與

3、其發(fā)出的順序相同。 (4)全雙工方式傳輸。 (5)數(shù)據(jù)以字節(jié)流的方式傳輸。 (6)傳輸?shù)臄?shù)據(jù)無消息邊界。 在TCP工作時,底層Socket詳細的通信流程如圖3.3所示。 同步工作方式是指利用TCP編寫的程序執(zhí)行到監(jiān)聽或接收語句時,在未完成 工作(偵聽到連接請求或收到對方發(fā)來的數(shù)據(jù))前不再繼續(xù)往下執(zhí)行,線程處于 阻塞狀態(tài),直到該語句完成相應的工作后才繼續(xù)執(zhí)行下一條語句。 異步工作方式是指程序執(zhí)行到監(jiān)聽或接收語句時,不論工作是否完成,都會 繼續(xù)往下執(zhí)行。 3.3.1 TcpListener類類 TcpListener類用于監(jiān)聽和接收傳入的連接請求。該類的構造函數(shù)常用的有以 下兩種重載形式: Tcp

4、Listener(IPEndPoint iep) TcpListener(IPAddress localAddr, int port) 在同步工作方式下,對應有: (1)Start方法。 (2)Stop方法。 (3)AcceptSocket方法。 (4)AcceptTcpClient方法。 表3-1列出了TcpListener類的常用方法。 方法方法說明說明 AcceptSocket從端口處接收一個連接并賦予它Socket對象 AcceptTcpClient從端口處接收一個連接并賦予它TcpClient對象 Equals判斷兩個TcpListener對象是否相等 GetHashCode用作特定

5、類型的哈希函數(shù) GetType得到當前實例類型 Pending確定是否有掛起的連接請求 Start開始偵聽傳入的連接請求 Stop關閉偵聽器 ToString創(chuàng)建TcpListener對象的字符串表示 TcpClient的構造函數(shù)有以下4種重載形式。 (1)TcpClient( )。 該構造函數(shù)創(chuàng)建一個默認的TcpClient對象,并自動分配本機(客戶端)IP 地址和端口號。利用此構造函數(shù)創(chuàng)建對象后,還必須調(diào)用Connect方法與服務器 建立連接。例如: TcpClient tcpClient = new TcpClient(); tcpClient.Connect(“”, 51888); (

6、2)TcpClient(AddressFamily family)。 構造函數(shù)創(chuàng)建的TcpClient對象也能自動分配本機(客戶端)IP地址和端口 號,但是使用AddressFamily枚舉指定使用哪種網(wǎng)絡協(xié)議。創(chuàng)建該對象后,必須 調(diào)用Connect方法與服務器建立連接。例如: TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork); tcpClient.Connect(“”, 51888); (3)TcpClient(IPEndPoint iep)。 如果使用這種方式,必須調(diào)用Connect方法與服務器建立連接。例如:

7、IPAddress address = Dns.GetHostAddresses (Dns.GetHostName(); IPEndPoint iep = new IPEndPoint (address0, 51888); TcpClient tcpClient = new TcpClient(iep); tcpClient.Connect(“”, 51888); (4)TcpClient(string hostname, int port)。 該構造函數(shù)會自動分配最合適的本地主機IP地址和端口號,并對DNS進行 解析,然后與遠程主機建立連接。例如: TcpClient tcpClient =

8、 new TcpClient(“”, 51888); 它相當于: TcpClient tcpClient = new TcpClient(); tcpClient Connect(“”, 51888); 表3-2和表3-3分別列出了TcpClient類的常用屬性和方法。 屬性屬性含義含義 Client獲取或設置基礎套接字 LingerState獲取或設置套接字保持連接的時間 NoDelay獲取或設置一個值,該值在發(fā)送或接收緩沖區(qū)未滿時禁用延遲 ReceiveBufferSize獲取或設置Tcp接收緩沖區(qū)的大小 ReceiveTimeout獲取或設置套接字接收數(shù)據(jù)的超時時間 SendBuffer

9、Size獲取或設置Tcp發(fā)送緩沖區(qū)的大小 SendTimeout獲取或設置套接字發(fā)送數(shù)據(jù)的超時時間 方法方法含義含義 Close釋放TcpClient實例,而不關閉基礎連接 Connect用指定的主機名和端口號將客戶端連接到TCP主機 BeginConnect開始一個對遠程主機連接的異步請求 EndConnect異步接受傳入的連接嘗試 GetStream獲取能夠發(fā)送和接收數(shù)據(jù)的NetworkStream對象 3.4.1編寫服務器端程序的一般步驟編寫服務器端程序的一般步驟 使用對套接字封裝后的類,編寫基于TCP的服務器端程序的一般步驟如下。 (1)創(chuàng)建一個TcpListener對象,然后調(diào)用該對

10、象的Start方法在指定的端口進 行監(jiān)聽。典型代碼如: /聲明 private IPAddress localAddress;/IP地址 private const int port = 51888;/端口 private TcpListener tcpListener;/監(jiān)聽套接字 /初始化 IPAddress listenIp = Dns.GetHostAddresses(); localAddress = listenIp0;/初始化IP為本地地址 /創(chuàng)建TcpListener對象,開啟監(jiān)聽 tcpListener = new TcpListener(localAddress, port

11、); tcpListener.Start();/監(jiān)聽開始 (2)在單獨的線程中,循環(huán)調(diào)用AcceptTcpClient方法接受客戶端的連接請 求,從該方法的返回結果中得到與該客戶端對應的TcpClient對象,并利用該對 象的GetStream方法得到NetworkStream對象,然后再利用該對象得到其他使用 更方便的對象如BinaryReader對象、BinaryWriter對象,為進一步與對方通信作 準備。 (3)每得到一個新的TcpClient對象,就創(chuàng)建一個與該客戶對應的線程,在 線程中與對應的客戶進行通信。 Thread threadReceive = new Thread(Rec

12、eiveMessage); threadReceive.Start(); (4)根據(jù)傳送信息的情況確定是否關閉與客戶的連接。 關閉連接的代碼: if (br != null) br.Close(); if (bw != null) bw.Close(); if (tcpClient != null) tcpClient.Close(); toolStripStatusInfo.Text = 連接斷開!; 使用對套接字封裝后的類,編寫基于TCP的客戶端程序的一般步驟如下。 (1)利用TcpClient的構造函數(shù)創(chuàng)建一個TcpClient對象。 private TcpClient tcpClien

13、t; tcpClient = new TcpClient(); (2)使用Connect方法與服務器建立連接。 tcpClient.Connect(remoteHost.HostName, int.Parse(tbxPort.Text); (3)利用TcpClient對象的GetStream方法得到網(wǎng)絡流,然后利用該網(wǎng)絡流與 服務器進行數(shù)據(jù)傳輸。 if (tcpClient != null) statusStripInfo.Invoke(shwStatusInfoCallBack, 連接成功!); networkStream = tcpClient.GetStream(); br = new

14、BinaryReader(networkStream); bw = new BinaryWriter(networkStream); (4)創(chuàng)建一個線程監(jiān)聽指定的端口,循環(huán)接收并處理服務器發(fā)送過來的信息。 Thread threadReceive = new Thread(ReceiveMessage); threadReceive.Start(); (5)完成工作后,向服務器發(fā)送關閉信息,并關閉與服務器的連接。 3.5.1 界面設計界面設計 服務器與客戶端程序設計簡潔清晰風格的界面,如圖3.5所示。 程序界面上控件的屬性描述見表3-4和表3-5。 Name控件類型控件類型功能描述功能描述 f

15、rmSyncTcpClientForm程序主窗體 lstbxMsgViewListBox接收消息顯示 tbxSendCountTextBox設置消息發(fā)送數(shù) tbxReceiveCountTextBox設置消息接收數(shù) btnClearButton【清空】按鈕 btnReceiveButton【接收】按鈕 tbxMsgTextBox編輯待發(fā)信息 btnSendButton【發(fā)送】按鈕 tbxSrvIpTextBox填寫服務器IP tbxPortTextBox填寫服務端口 btnConnectButton【連接】按鈕 btnDisconnectButton【斷開】按鈕 toolStripStatus

16、InfoToolStripStatusLabel狀態(tài)欄文本標簽 toolStripProgressProcToolStripProgressBar狀態(tài)欄進度條 statusStripInfoStatusStrip狀態(tài)欄 Name控件類型控件類型功能描述功能描述 frmSyncTcpServerForm程序主窗體 lstbxMsgViewListBox接收消息顯示 tbxSendCountTextBox設置消息發(fā)送數(shù) tbxReceiveCountTextBox設置消息接收數(shù) btnClearButton【清空】按鈕 btnReceiveButton【接收】按鈕 tbxMsgTextBox編輯待

17、發(fā)信息 btnSendButton【發(fā)送】按鈕 btnStartButton【開始偵聽】按鈕 btnStopButton【關閉偵聽】按鈕 btnDisconnectButton【斷開】按鈕 toolStripStatusInfoToolStripStatusLabel狀態(tài)欄文本標簽 toolStripProgressProcToolStripProgressBar狀態(tài)欄進度條 statusStripInfoStatusStrip狀態(tài)欄 表表3-5同步服務器端界面控件描述同步服務器端界面控件描述 首先聲明4個委托:ShwMsgforViewCallBack、ShwStatusInfoCallBa

18、ck、 ShwProgressProcCallBack和ResetMsgTxtCallBack,然后將它們的實例分別綁 定到定義好的4個函數(shù)(回調(diào)方法):ShwMsgforView、ShwStatusInfo、 ShwProgressProc和ResetMsgTxt,通過回調(diào)方法間接地執(zhí)行各自對應的界面 操作:列表顯示收到的消息、顯示狀態(tài)信息、顯示進度和重置待發(fā)送的消息文 本。這是編寫“線程安全”的程序時操作界面控件的普遍方法,整個程序的完 整代碼。 與客戶端程序一樣,首先搭建好應用委托回調(diào)機制的框架,整個程序的完 整代碼。 運行服務器和客戶端程序,如圖3.6所示。 1. 服務器接受請求(服務

19、器接受請求(tcpClient = tcpListener.AcceptTcpClient();) 單擊服務器【開始偵聽】按鈕,如圖3.7所示。 單擊客戶進程【連接】按鈕,向服務器發(fā)起連接請求,產(chǎn)生的現(xiàn)象如圖3.8 所示。 2. 接收數(shù)據(jù)(接收數(shù)據(jù)(string rcvMsgStr = br.ReadString();) 單擊服務器【接收】按鈕,如圖3.9所示。 設置客戶端發(fā)送消息數(shù)為5,編輯消息內(nèi)容后,單擊“發(fā)送”按鈕,運行效 果如圖3.10所示。 單擊客戶端【發(fā)送】按鈕,再發(fā)送5條消息,如圖3.11所示。 3. 發(fā)送數(shù)據(jù)(發(fā)送數(shù)據(jù)(bw.Write(state.ToString();) 在

20、服務器接收線程未開啟的情況下,從客戶端向服務器發(fā)消息,如圖3.12 所示。 客戶端發(fā)送完畢后,服務器并無反應。只有在單擊服務器【接收】按鈕后, 才能看到收到的消息,如圖3.13所示,發(fā)送消息后對方卻是異步收到的! 3.6.1 異步程序設計異步程序設計 1. 基于基于IAsyncResult的異步設計模式的異步設計模式 (1)基本原理。 基于IAsyncResult的異步設計模式通過前綴分別為“Begin”和“End”的 兩個方法實現(xiàn)開始和結束異步操作,每個Begin方法都必須有一個與其對應的 End方法,如BeginAcceptTcpClient和EndAcceptTcpClient方法等。

21、(2)AsyncCallback委托。 AsyncCallback委托用于在異步操作完成時調(diào)用指定的回調(diào)方法。 2. 異步異步TCP編程常用方法編程常用方法 表3-6列出了TcpListener類、TcpClient類提供的部分異步操作方法。 類類方法方法說明說明 TcpListener BeginAcceptTcpClient開始一個異步操作接受一個傳入的連接嘗試 EndAcceptTcpClient 異 步 接 受 傳 入 的 連 接 嘗 試 , 并 創(chuàng) 建 新 的 TcpClient處理遠程主機通信 TcpClient BeginConnect開始一個對遠程主機連接的異步請求 EndCo

22、nnect異步接受傳入的連接嘗試 3. 異步方式調(diào)用同步方法異步方式調(diào)用同步方法 (1)聲明與要調(diào)用的方法具有相同簽名的委托。 下面的代碼說明了如何聲明一個與要調(diào)用的方法具有相同簽名的委托: private BinaryWriter bw; private delegate void SendMessageDelegate(string sendMessage); private SendMessageDelegate sendMessageDelegate; sendMessageDelegate = new SendMessageDelegate(AsyncSndMsg); private

23、 void AsyncSndMsg(string sendMessage) try bw.Write(sendMessage); bw.Flush(); catch (2)通過輪詢方式檢查異步調(diào)用是否完成。 聲明和AsyncSndMsg方法具有相同簽名的委托以后,公共語言運行時就會 自動為該委托定義Beginlnvoke方法和Endlnvoke方法。然后就可以異步調(diào)用 AsyncSndMsg方法了。 調(diào)用Beginlnvoke方法后,該方法會立即返回IAsyncResult類型的接口,從 用戶界面的服務線程中進行異步調(diào)用時,可以利用該接口的IsCompleted屬性來 通過輪詢方式檢查異步調(diào)用

24、是否完成。 在輪詢過程中,Beginlnvoke方法在ThreadPool中創(chuàng)建的線程會繼續(xù)執(zhí)行異 步方法。例如: private bool needExit; IAsyncResult result = sendMessageDelegate.BeginInvoke(sendMessage, null, null); while (result.IsCompleted = false) if (needExit) break; Thread.Sleep (50); (3)使用Endlnvoke結束異步調(diào)用。 Endlnvoke方法用于檢索異步調(diào)用的結果,并結束異步調(diào)用。調(diào)用 Beginlnv

25、oke之后,隨時可以調(diào)用該方法。如果異步調(diào)用尚未完成,則 Endlnvoke會一直阻止調(diào)用線程,直到異步調(diào)用完成。例如,在退出輪詢后,可 以直接通過下面的代碼結束異步調(diào)用: sendMessageDelegate.EndInvoke(result); 給這個程序設計與3.5節(jié)程序一模一樣的界面,只在窗體標題中注明這是異 步程序,如圖3.14所示。 程序界面上控件的屬性描述見表3-7和表3-8。 Name控件類型控件類型功能描述功能描述 frmAsyncTcpClientForm程序主窗體 lstbxMsgViewListBox接收消息顯示 tbxSendCountTextBox設置消息發(fā)送數(shù)

26、tbxReceiveCountTextBox設置消息接收數(shù) btnClearButton【清空】按鈕 btnReceiveButton【接收】按鈕 tbxMsgTextBox編輯待發(fā)信息 btnSendButton【發(fā)送】按鈕 tbxSrvIpTextBox填寫服務器IP tbxPortTextBox填寫服務端口 btnConnectButton【連接】按鈕 btnDisconnectButton【斷開】按鈕 toolStripStatusInfoToolStripStatusLabel狀態(tài)欄文本標簽 toolStripProgressProcToolStripProgressBar狀態(tài)欄進度

27、條 statusStripInfoStatusStrip狀態(tài)欄 Name控件類型控件類型功能描述功能描述 frmAsyncTcpServerForm程序主窗體 lstbxMsgViewListBox接收消息顯示 tbxSendCountTextBox設置消息發(fā)送數(shù) tbxReceiveCountTextBox設置消息接收數(shù) btnClearButton【清空】按鈕 btnReceiveButton【接收】按鈕 tbxMsgTextBox編輯待發(fā)信息 btnSendButton【發(fā)送】按鈕 btnStartButton【開始偵聽】按鈕 btnStopButton【關閉偵聽】按鈕 btnDisco

28、nnectButton【斷開】按鈕 toolStripStatusInfoToolStripStatusLabel狀態(tài)欄文本標簽 toolStripProgressProcToolStripProgressBar狀態(tài)欄進度條 statusStripInfoStatusStrip狀態(tài)欄 表表3-8異步服務器端界面控件描述異步服務器端界面控件描述 首先搭建好應用委托回調(diào)機制的通用框架,聲明4個委托: ShwMsgforViewCallBack、ShwStatusInfoCallBack、 ShwProgressProcCallBack和ResetMsgTxtCallBack,然后將它們的實例分別 綁定到定義好的4個函數(shù)(回調(diào)方法):ShwMsgforView、ShwStatusInfo、 ShwProgressProc和ResetMsgTxt。 整個程序的完整代碼。 與客戶端程序一樣,首先搭建好應用委托回調(diào)機制的框架。由于這是異步服 務器端,故如前一樣,要專門定義兩個異步操作方法AsyncRcvMsg和 AsyncSndMsg,分別用來接收和發(fā)送信息,并且事先聲明和實例化與它們具有 相同簽名的委托ReceiveMessageDelegate和SendMessageDele

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論