C_網(wǎng)絡(luò)編程---第2章_TCP應(yīng)用編程.ppt_第1頁
C_網(wǎng)絡(luò)編程---第2章_TCP應(yīng)用編程.ppt_第2頁
C_網(wǎng)絡(luò)編程---第2章_TCP應(yīng)用編程.ppt_第3頁
C_網(wǎng)絡(luò)編程---第2章_TCP應(yīng)用編程.ppt_第4頁
C_網(wǎng)絡(luò)編程---第2章_TCP應(yīng)用編程.ppt_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第2章 TCP應(yīng)用編程,2.1 同步TCP應(yīng)用編程 2.2 利用同步TCP編寫網(wǎng)絡(luò)游戲 2.3 異步TCP應(yīng)用編程 2.4 異步TCP聊天程序,TCP是Transmission Control Protocol(傳輸控 制協(xié)議)的簡稱,是TCP/IP體系中面向連接的運 輸層協(xié)議,在網(wǎng)絡(luò)中提供全雙工的和可靠的服務(wù)。 TCP協(xié)議最主要的特點是: 1) 是一種基于連接的協(xié)議。 2) 保證數(shù)據(jù)準(zhǔn)確到達(dá)。 3) 保證各數(shù)據(jù)到達(dá)的順序與數(shù)據(jù)發(fā)出的順序相同。 4) 傳輸?shù)臄?shù)據(jù)無消息邊界。,關(guān)于TCP應(yīng)用編程的幾個概念:,1)同步工作方式 用TCP協(xié)議進行編程時程序執(zhí)行到發(fā)送、接收和監(jiān)聽語句時,在未完成工作前

2、不再繼續(xù)往下執(zhí)行,即處于阻塞狀態(tài),直到該語句完成某個工作后才繼續(xù)執(zhí)行下一條語句。 2)異步工作方式 程序執(zhí)行到發(fā)送、接收和監(jiān)聽語句時,不論工作是否完成,都會繼續(xù)往下執(zhí)行。,3)同步套接字編程 與同步工作方式相對應(yīng)的,利用Socket類進行編程時系統(tǒng)提供有相應(yīng)的方法,采用相應(yīng)的方法進行編程則稱為同步套接字編程。 4)異步套接字編程 與異步工作方式相對應(yīng)的,利用Socket類進行編程時系統(tǒng)提供有相應(yīng)的方法,采用相應(yīng)的方法進行編程則稱為異步套接字編程 。 這里的同步TCP和異步TCP僅僅指工作方式,它和第1章介紹的線程間的同步不是一個概念。,2.1 同步TCP應(yīng)用編程,在同步TCP應(yīng)用編程中,發(fā)送、

3、接收和監(jiān)聽語句均采用阻塞方式工作。 使用同步TCP編寫服務(wù)器端程序的一般步驟為: 1) 創(chuàng)建一個包含采用的網(wǎng)絡(luò)類型、數(shù)據(jù)傳輸類型和協(xié)議類型的本地套接字對象,并將其與服務(wù)器的IP地址和端口號綁定。此過程可以通過Socket類或者TcpListener類完成。 2) 在指定的端口進行監(jiān)聽,以便接受客戶端連接請求。,2.1 同步TCP應(yīng)用編程(續(xù)),3) 一旦接受了客戶端的連接請求,就根據(jù)客戶端發(fā)送的連接信息創(chuàng)建與該客戶端對應(yīng)的Socket對象或者TcpClient對象。 4) 根據(jù)創(chuàng)建的Socket對象或者TcpClient對象,分別與每個連接的客戶進行數(shù)據(jù)傳輸。 5) 根據(jù)傳送信息情況確定是否關(guān)

4、閉與對方的連 接。,2.1 同步TCP應(yīng)用編程(續(xù)),使用同步TCP編寫客戶端程序的一般步驟為: 1) 創(chuàng)建一個包含傳輸過程中采用的網(wǎng)絡(luò)類型、數(shù)據(jù)傳輸類型和協(xié)議類型的Socket對象或TcpClient對象。 2) 使用Connect方法與遠(yuǎn)程服務(wù)器建立連接。 3) 與服務(wù)器進行數(shù)據(jù)傳輸。 4) 完成工作后,向服務(wù)器發(fā)送關(guān)閉信息,并關(guān)閉與服務(wù)器的連接。,2.1.1 使用套接字發(fā)送和接收數(shù)據(jù),服務(wù)器與客戶端雙方建立連接后,程序中需要先將要發(fā)送的數(shù)據(jù)轉(zhuǎn)換為字節(jié)數(shù)組,然后使用Socket對象的Send方法發(fā)送數(shù)據(jù),或者使用Receive方法接收數(shù)據(jù)。,2.1.2 使用NetworkStream對象發(fā)

5、送和接收數(shù)據(jù),NetworkStream對象專門用于對網(wǎng)絡(luò)流數(shù)據(jù)進行處理。創(chuàng)建了NetworkStream對象后,就可以直接使用該對象接收和發(fā)送數(shù)據(jù)。例如: NetworkStream networkStream = new NetworkStream(clientSocket ); /發(fā)送數(shù)據(jù) string message = 發(fā)送的數(shù)據(jù);,2.1.2 使用NetworkStream對象發(fā)送和接收數(shù)據(jù)(續(xù)),byte sendbytes = System.Text.Encoding.UTF8.GetBytes(message ); networkStream.Write(sendbytes

6、,0, sendbytes.Length ); /接收數(shù)據(jù) byte readbytes = new byte1024; int i = networkStream.Read(readbytes, 0, readbytes.Length); NetworkStream對象的Write方法能保證字節(jié)數(shù) 組中的數(shù)據(jù)全部發(fā)送到TCP發(fā)送緩沖區(qū)中,其返回 值為void。,2.1.3 TcpClient與TcpListener類,在System.Net.Sockets命名空間下,TcpClient類 與TcpListener類是兩個專門用于TCP協(xié)議編程的 類。這兩個類封裝了底層的套接字,并分別提供了

7、對Socket進行封裝后的同步和異步操作的方法,降 低了TCP應(yīng)用編程的難度。 TcpClient類用于連接、發(fā)送和接收數(shù)據(jù)。 TcpListener類則用于監(jiān)聽是否有傳入的連接請求。,2.1.3 TcpClient與TcpListener類(續(xù)),1. TcpClient類 TcpClient類歸類在System.Net命名空間下。 利用TcpClient類提供的方法,可以通過網(wǎng)絡(luò)進 行連接、發(fā)送和接收網(wǎng)絡(luò)數(shù)據(jù)流。該類的構(gòu)造函數(shù) 有四種重載形式:,1) TcpClient() 該構(gòu)造函數(shù)創(chuàng)建一個默認(rèn)的TcpClient對象,該對象自動選擇客戶端尚未使用的IP地址和端口號。創(chuàng)建該對象后,即可用

8、Connect方法與服務(wù)器端進行連接。例如:,2.1.3 TcpClient與TcpListener類(續(xù)),TcpClient tcpClient=new TcpClient(); tcpClient.Connect(, 51888);,2) TcpClient(AddressFamily family) 該構(gòu)造函數(shù)創(chuàng)建的TcpClient對象也能自動選擇客戶端尚未使用的IP地址和端口號,但是使用AddressFamily枚舉指定了使用哪種網(wǎng)絡(luò)協(xié)議。創(chuàng)建該對象后,即可用Connect方法與服務(wù)器端進行連接。例如: TcpClient tcpClient = new TcpClient(Add

9、ressFamily.InterNetwork); tcpClient.Connect(, 51888);,2.1.3 TcpClient與TcpListener類(續(xù)),3) TcpClient(IPEndPoint iep) iep是IPEndPoint類型的對象,iep指定了客戶端的IP地址與端口號。當(dāng)客戶端的主機有一個以上的IP地址時,可使用此構(gòu)造函數(shù)選擇要使用的客戶端主機IP地址。例如: IPAddress address = Dns.GetHostAddresses(Dns.GetHostName(); IPEndPoint iep = new IPEndPoint(address

10、0, 51888); TcpClient tcpClient = new TcpClient(iep); tcpClient.Connect(, 51888);,2.1.3 TcpClient與TcpListener類(續(xù)),4) TcpClient(string hostname,int port) 這是使用最方便的一種構(gòu)造函數(shù)。該構(gòu)造函數(shù)可直接指定服務(wù)器端域名和端口號,而且不需使用connect方法??蛻舳酥鳈C的IP地址和端口號則自動選擇。例如: TcpClient tcpClient=new TcpClient(, 51888);,2.1.3 TcpClient與TcpListener類

11、(續(xù)),2. TcpListener類 TcpListener類用于監(jiān)聽和接收傳入的連接請求。該類的構(gòu)造函數(shù)有: 1) TcpListener(IPEndPoint iep) 該構(gòu)造函數(shù)通過IPEndPoint類型的對象在指定 的IP地址與端口監(jiān)聽客戶端連接請求。 2) TcpListener(IPAddress localAddr, int port) 建立一個TcpListener對象,在參數(shù)中直接指定本機IP地址和端口,并通過指定的本機IP地址和端口號監(jiān)聽傳入的連接請求。,2.1.3 TcpClient與TcpListener類(續(xù)),在同步工作方式下, TcpListener類對應(yīng)的方

12、法: AcceptTcpClient:在同步阻塞方式下獲取并返回一個用來接收和發(fā)送數(shù)據(jù)的套接字對象 ; 2) AcceptSocket:在同步阻塞方式下獲取并返回一個可以用來接收和發(fā)送數(shù)據(jù)的封裝了Socket的TcpClient對象 ;,3) Start:啟動監(jiān)聽,其構(gòu)造函數(shù)為: public void Start(int backlog) 整型參數(shù)backlog為請求隊列的最大長度,即最多允許的客戶端連接個數(shù); 4) Stop:停止監(jiān)聽請求,構(gòu)造函數(shù)為: public void Stop();,2.1.4 解決TCP協(xié)議的無消息邊界問題,有三種: 第一種方法是發(fā)送固定長度的消息。該方法適用

13、于消息長度固定的場合。 第二種方法是將消息長度與消息一起發(fā)送。 第三種方法是使用特殊標(biāo)記分隔消息。,2.2 利用同步TCP編寫網(wǎng)絡(luò)游戲,這個稍微復(fù)雜的“吃棋子”游戲是利用TCP協(xié)議和同步套接字以及多線程編寫的網(wǎng)絡(luò)應(yīng)用程序。具體規(guī)則及功能見課本。,1.服務(wù)器端編程 服務(wù)器啟動服務(wù)后,需要創(chuàng)建一個線程專門用于監(jiān)聽玩家的連接請求。在監(jiān)聽線程中,服務(wù)器一旦接受一個連接,就創(chuàng)建一個與該玩家對應(yīng)的線程,用于接收該玩家發(fā)送的信息,并根據(jù)該玩家發(fā)送的信息提供相應(yīng)的服務(wù)。 有多少個玩家連接,就創(chuàng)建多少個對應(yīng)的線程。玩家退出游戲室,其對應(yīng)的線程自動終止。 在與每個玩家對應(yīng)的線程中,服務(wù)器收到對應(yīng)玩 家發(fā)送的字符串

14、信息后,需要解析字符串的含義, 并決定服務(wù)器需要的操作。,2.2 利用同步TCP編寫網(wǎng)絡(luò)游戲(續(xù)),2.客戶端編程 客戶端與服務(wù)器連接成功后,需要創(chuàng)建一個接收線程,用于接收服務(wù)器發(fā)送的信息。在接收線程中,客戶端收到服務(wù)器發(fā)送的字符串信息后,需要解析字符串的含義,并決定需要的操作。 另外,客戶端還需要根據(jù)服務(wù)器發(fā)送的命令,及時更新客戶端程序的運行界面 。,2.2 利用同步TCP編寫網(wǎng)絡(luò)游戲(續(xù)),3.代碼見課本,2.3 異步TCP應(yīng)用編程,TcpListener類 1) BeginAcceptTcpClient:開始一個異步操作接受一個傳入的連接嘗試。 2) EndAcceptTcpClient

15、:異步接受傳入的連接嘗試并創(chuàng)建新的TcpClient處理遠(yuǎn)程主機通信。 TcpClient類 1) BeginConnect:開始一個對遠(yuǎn)程主機連接的異步請求。 2) EndConnect:異步接受傳入的連接嘗試。,2.3 異步TCP應(yīng)用編程(續(xù)),Socket類 1) BeginReceive: 開始從連接的Socket中異步接收數(shù)據(jù)。 2) EndReceive: 結(jié)束掛起的異步讀取。 3) BeginSend: 將數(shù)據(jù)異步發(fā)送到連接的Socket。 4) EndSend: 結(jié)束掛起的異步發(fā)送。,2.3.1 EventWaitHandle類,System.Threading命名空間下的Ev

16、entWaitHandle 類,用于在異步操作時控制線程間的同步,即控制 一個或多個線程繼續(xù)執(zhí)行或者等待其它線程完成。 也就是,需要同步的線程可以先阻塞當(dāng)前線程,然 后根據(jù)Windows操作系統(tǒng)發(fā)出的信號,決定是繼續(xù) 阻塞等待其它工作完成,還是不再等待而直接往下 執(zhí)行。,2.3.1 EventWaitHandle類(續(xù)),EventWaitHandle類提供的方法有: 1) Reset:將信號的狀態(tài)設(shè)置為非終止?fàn)顟B(tài),即不讓操作系統(tǒng)發(fā)出信號,從而導(dǎo)致等待收到信號才能繼續(xù)執(zhí)行的線程阻塞。 2) Set:將事件狀態(tài)設(shè)置為終止?fàn)顟B(tài),這樣等待的線程將會收到信號,從而繼續(xù)執(zhí)行而不再等待。 3) WaitO

17、ne:阻塞當(dāng)前線程,等待操作系統(tǒng)為其發(fā)出信號,直到收到信號才解除阻塞。,2.3.1 EventWaitHandle類(續(xù)),操作系統(tǒng)發(fā)出信號的方式有兩種: 1) 發(fā)一個信號,使某個等待信號的線程解除阻塞,繼續(xù)執(zhí)行。 2) 發(fā)一個信號,使所有等待信號的線程全部解除阻塞,繼續(xù)執(zhí)行。,2.3.2 AsynCallback委托,AsyncCallback委托用于引用異步操作完成時調(diào) 用的回調(diào)方法。在異步操作方式下,由于程序可以 在啟動異步操作后繼續(xù)執(zhí)行其他代碼,因此必須有 一種機制,以保證該異步操作完成時能及時通知調(diào) 用者。這種機制可以通過AsyncCallback委托實現(xiàn)。 異步操作的每一個方法都有

18、一個Begin方法和 End方法,例如BeginAcceptTcpClient和 EndAcceptTcpClient。程序調(diào)用Begin方法時, 系統(tǒng)會自動在線程池中創(chuàng)建對應(yīng)的線程進行異步操 作,從而保證調(diào)用方和被調(diào)用方同時執(zhí)行,當(dāng)線程,2.3.2 AsynCallback委托(續(xù)),池中的Begin方法執(zhí)行完畢時,會自動通過 AsyncCallback委托調(diào)用在Begin方法的參數(shù)中指 定的回調(diào)方法。 回調(diào)方法是在程序中事先定義的,在回調(diào)方法 中,通過End方法獲取Begin方法的返回值和 所有輸入/輸出參數(shù),從而達(dá)到異步操作方式下完 成參數(shù)傳遞的目的。,2.3.3 BeginAccept

19、TcpClient與EndAcceptTcpClient方法,這兩個方法包含在System.Net.Sockets命名空間 下的TcpListener類中。 在BeginAcceptTcpClient方法中,系統(tǒng)自動利用 線程池創(chuàng)建需要的線程,同時監(jiān)聽客戶端連接請 求。一旦接受了客戶連接請求,就自動通過委托調(diào) 用提供給委托的方法,并返回狀態(tài)信息。該方法的 原型為: public IAsyncResult BeginAcceptTcpClient (AsyncCallback callback, Object state),2.3.3 BeginAcceptTcpClient與EndAccept

20、TcpClient方法(續(xù)),其中:參數(shù)1為AsyncCallback類型的委托;參數(shù) 2為Object類型,用于將狀態(tài)信息傳遞給委托提供 的方法。例如: AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallback); tcpListener.BeginAcceptTcpClient(callback, tcpListener);,2.3.3 BeginAcceptTcpClient與EndAcceptTcpClient方法(續(xù)),void AcceptTcpClientCallback( IAsyncResult ar

21、) 回調(diào)代碼 AcceptTcpClientCallback方法中傳遞的參數(shù)只有 一個,而且必須是IAsyncResult類型的接口,它表 示異步操作的狀態(tài)。系統(tǒng)會自動將該狀態(tài)信息從關(guān) 聯(lián)的BeginAcceptTcpClient方法傳遞到 AcceptTcpClientCallback方法。在回調(diào)代碼中,必 須調(diào)用EndAcceptTcpClient方法完成客戶端連接。 關(guān)鍵代碼為:,2.3.3 BeginAcceptTcpClient與EndAcceptTcpClient方法(續(xù)),void AcceptTcpClientCallback( IAsyncResult ar) TcpList

22、ener myListener = (TcpListener)ar.AsyncState; TcpClient client = myListener.EndAcceptTcpClient(ar); 默認(rèn)情況下,程序執(zhí)行BeginAcceptTcpClient方 法后,在該方法返回狀態(tài)信息之前,不會像同步 TCP方式那樣阻塞等待客戶端連接,而是繼續(xù)往下 執(zhí)行。,2.3.4 BeginConnect與EndConnect 方法,BeginConnect方法和EndConnect方法包含在命 名空間System.Net.Sockets下的TcpClient類和 Socket類中 。 在異步TCP應(yīng)

23、用編程中,BeginConnect方法通過 異步方式向遠(yuǎn)程主機發(fā)出連接請求。該方法有三種 重載的形式,方法原型為: public IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback requestCallback, Object state);,2.3.4 BeginConnect與EndConnect 方法(續(xù)),public IAsyncResult BeginConnect(IPAddress addresses, int port, AsyncCallback requestCallback, Obj

24、ect state); public IAsyncResult BeginConnect(string host, int port, AsyncCallback requestCallback, Object state); 其中address為遠(yuǎn)程主機的IPAddress對象;port 為遠(yuǎn)程主機的端口號;requestCallback為 AsyncCallback類型的委托;state為包含連接操作 的相關(guān)信息,當(dāng)操作完成時,此對象會被傳遞給 requestCallback委托。,2.3.4 BeginConnect與EndConnect 方法(續(xù)),異步BeginConnect方法只有

25、在調(diào)用了EndConnect方 法之后才算執(zhí)行完畢。因此程序中需要在提供給 requestCallback委托調(diào)用的方法中調(diào)用TcpClient 對象的EndConnect方法。關(guān)鍵代碼為: AsyncCallback requestCallback = new AsyncCallback(RequestCallback); tcpClient.BeginConnect(遠(yuǎn)程主機IP或域名,遠(yuǎn)程主機端口號 , requestCallback, tcpClient); ,2.3.4 BeginConnect與EndConnect 方法(續(xù)),void RequestCallback(IAsync

26、Result ar) tcpClient = (TcpClient)ar.AsyncState; client.EndConnect(ar); 在自定義的RequestCallback中,通過獲取的狀 態(tài)信息得到新的TcpClient類型的對象,并調(diào)用 EndConnect結(jié)束連接請求。,2.3.5 發(fā)送數(shù)據(jù),在異步TCP應(yīng)用編程中,在本機已經(jīng)和遠(yuǎn)程主機 建立連接的前提下,可以用System.Net.Sockets命 名空間下NetworkStream類中的BeginWrite方法發(fā) 送數(shù)據(jù)。其方法原型為: public override IAsyncResult BeginWrite(byt

27、e buffer, int offset, int size, AsyncCallback callback, Object state); 其中buffer是一組Byte類型的值,用來存放要發(fā) 送的數(shù)據(jù)。offset用來存放發(fā)送的數(shù)據(jù)在發(fā)送緩沖 區(qū)中的起始位置。size用來存放發(fā)送數(shù)據(jù)的字節(jié) 數(shù)。callback是異步回調(diào)類型的委托,state包含狀 態(tài)信息。,2.3.5 發(fā)送數(shù)據(jù)(續(xù)),使用BeginWrite方法異步發(fā)送數(shù)據(jù),程序必須創(chuàng) 建實現(xiàn)AsyncCallback委托的回調(diào)方法,并將其名 稱傳遞給BeginWrite方法。在BeginWrite方法中, 狀態(tài)信息必須至少包含Netw

28、orkStream對象。程序 調(diào)用BeginWrite后,系統(tǒng)自動使用單獨的線程來執(zhí) 行指定的回調(diào)方法,并在EndWrite上一直處于阻 塞狀態(tài),直到NetworkStream對象發(fā)送請求的字節(jié) 數(shù)或引發(fā)異常。關(guān)鍵代碼為:,2.3.5 發(fā)送數(shù)據(jù)(續(xù)), NetworkStream stream = tcpClient.GetStream(); byte bytesData = System.Text.Encoding.UTF8.GetBytes(str + rn); stream.BeginWrite(bytesData, 0, bytesData.Length, new AsyncCallb

29、ack(SendCallback), stream); stream.Flush(); ,2.3.5 發(fā)送數(shù)據(jù)(續(xù)),private void SendCallback(IAsyncResult ar) stream.EndWrite(ar); 若希望在BeginWrite方法得到傳遞的狀態(tài)信息之前使當(dāng)前線程(即調(diào)用BeginWrite方法的線程)阻塞,可以使用ManualResetEvent對象WaitOne方法。并在回調(diào)方法中調(diào)用Set使當(dāng)前線程繼續(xù)執(zhí)行。,2.3.6 接收數(shù)據(jù),如果本機已經(jīng)和遠(yuǎn)程主機建立了連接,就可以用 System.Net.Sockets命名空間下NetworkStream類中 的BeginRead方法接收數(shù)據(jù)。其方法原型為: public override IAsyncResult BeginRead(byte buffer, int offset, int size, AsyncCallback callback, object state); 其中buffer為字節(jié)數(shù)組,存儲從NetworkStream 讀取的數(shù)據(jù);offset為buffer中開始存儲數(shù)據(jù)的位 置;size為從NetworkStream中讀取的字節(jié)數(shù); callback是在BeginRead完成時執(zhí)行的AsyncCallback委 托;state包含

溫馨提示

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

評論

0/150

提交評論