程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Socket 兩平台互相 通信 .NET

Socket 兩平台互相 通信 .NET

編輯:C#入門知識

  兩個平台互相通信,對方發送數據過來,我方接收數據,對數據進行處理後發送結果給對方,對方進行相應的操作。

  提取實際有效數據:

            [] arrNew =  , arrNew, , arrLen);

  在對接收到的數據arrNew進行業務處理之後,將結果arrResult返回給對方,最後關閉連接:

       socket.Close();

  對上面代碼進行講解:首先,socket.Accept();這個方法,服務會一直停留在這個方法上面,等待客戶端的連接,一有客戶端連接上來,才會繼續執行下面的代碼。如果沒有客戶端來連接服務,程序將會一直停留在這個地方,會出現“假死”的現象。其次,上面的代碼示例只能處理一個客戶端的連接請求,請求處理完成後,就會關閉連接。服務端應該是一個永不會停止的程序,能夠一直監聽客戶端的請求,並對其進行處理和回饋。

  所以對上面的問題進行說明,首先使用線程,開啟服務後,服務端處理監聽狀態,當有客戶端連接請求上來後,為該客戶端連接新創建一個線程,專門來處理該客戶端的請求操作。當有多個客戶端連接上來後,服務會為每個客戶端都新創建線程來處理。這樣服務可以繼續監聽其他客戶端的連接請求,一邊又可以對已連接上來的客戶端進行響應處理。其次,要服務隊能夠永遠的監聽客戶端的連接請求,就必須讓服務端在處理完一個客戶端的連接請求後,能夠繼續調用socket.Accept()來監聽連接請求,這裡使用while(true){}無限循環來實現。

         isListener =  
         
        =[] arrMsg =  [ *  arrLen =[] arrNew =  , arrNew, 
= 

  由於本次需求上只有一個客戶端,所以這次沒有采用多線程的方式。只是在主線程上,新建一條線程專門用來監聽和處理客戶端的請求操作,這樣主線程還可以繼續執行它的任務,程序也不會出現“假死”的狀態。

  當然,對於客戶端發送過來的數據,服務端要能進行識別判斷,提取有效數據。所以在本次雙方通信過程中,對數據的格式進行了約定,只有遵循了格式的數據才會進行處理解析和響應。接口協議定義如下表所示(數據協議XML結構定義省略):

通訊數據包結構定義如表下: 包頭標記 總長 消息類型 XML流長度 XML格式數據 包尾標記 4B 4B 1B 4B   2B

 

數據包內各項目定義說明如下表: 序號 項目名稱 取值 說明 1  包頭 0xE1 0x2B 0xD3 0x78 取固定值 2 總長   4個字節(包括包頭包尾的長度) 3 消息類型 0x21 或者 0x22 用於區別數據包的類型 4 XML流長度   XML格式數據的長度(4bytes) 5 XML格式數據   為所傳遞的XML報文 6 包尾 0xFF 0xFF 取固定值

 

數據包協議類型說明如下表: 消息號 說明 XML格式 0x21 表示客戶端向服務端發送數據 XMLInfoSed 0x22 表示服務端向客戶端發送數據 XMLInfoReq

   定義好通信協議之後,Socket通信就需要遵循這個協議,服務端和客戶端都只接收該遵循該協議的報文和發送該格式的報文。

         isListener =  
         
        =[] arrMsg =  [ *   arrLen = (arrLen !=  (arrMsg[] == )
=  
                                Buffer.BlockCopy(arrMsg, , arrNew, , arrLen -  msg = Encoding.GetEncoding(= 

;
  (arrMsg[] == )
[] arrNew =  [
                                arrNew[] = ] = ] = ] = 
                                arrNew[] = [] xmlArr =  , xmlArr,  msg = Encoding.GetEncoding( hexLength = String.Format(
                                arrNew[] = Convert.ToByte(hexLength.Substring(, ), ] = Convert.ToByte(hexLength.Substring(, ), ] = Convert.ToByte(hexLength.Substring(, ), ] = Convert.ToByte(hexLength.Substring(, ), 
                                 dataLen = arrNew.Length + xmlArr.Length +  dataHexLen = String.Format(
                                arrNew[] = Convert.ToByte(dataHexLen.Substring(, ), ] = Convert.ToByte(dataHexLen.Substring(, ), ] = Convert.ToByte(dataHexLen.Substring(, ), ] = Convert.ToByte(dataHexLen.Substring(, ), [] newArr =  , newArr, - ] = - ] = 
                                Socket toclientSocket = ==  IPEndPoint(address,  [] {  });
 [] {  });                                 clientReqSocket.Close();
                                 = 

   在這裡本服務成為一個類似中轉站的機器,客戶端向本服務發送數據,本服務接收數據,對數據進行解析,解析完成後將數據交給後台系統,後台系統對數據進行業務邏輯處理後,將結果數據發送給本服務,然後本服務將最後結果數據發送給客戶端。原本不需要本服務中間這一環節,客戶端和後台系統可以直接進行通信交互,但是因為業務要求,所以必須要有本服務這一中間環節。

  對上面代碼進行說明:首頁本服務要先判斷接收到的數據為客戶端發送來的數據,還是後台系統需要向客戶端發送的數據。根據通信數據包結構定義,消息類型占1個字節,前面有包頭4字節和總長4字節共8個字節,所以消息類型在第9個字節的位置。對接收到的數據arrMsg[8]第9個字節進行判斷,如果arrMsg[8] = 0x22表示為客戶端發送來的數據,客戶端發送來的數據,本服務需要提取XML數據部分,然後對XML數據進行解析,將後台服務需要的數據發送給後台。

  Buffer.BlockCopy(arrMsg, 13, arrNew, 0, arrLen - 15);去除頭13個字節和尾2個字節,提取XML數據部分。

  如果arrMsg[8] == 0x22表示後台系統要向客戶端發送的數據,接收到後台系統發送過來的數據,首先要對數據進行封裝,將數據組裝成為約定好的XML結構(本服務接收到的數據就為XML數據),然後將該XML數據添加包頭包尾,重新封裝成為客戶端能夠識別的數據結構。將數據進行重新封裝後發送給客戶端,並且通知後台系統發送結果狀態。

  在這裡主要是想跟大家分享,在網絡通信過程中,對於有通信接口格式定義的該如何進行交互。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved