1. 程式人生 > >Unity3D研究院之C#使用Socket與HTTP連線伺服器傳輸資料包

Unity3D研究院之C#使用Socket與HTTP連線伺服器傳輸資料包

最近專案中需要使用HTTP與Socket,把自己這段時間學習的資料整理一下。有關Socket與HTTP的基礎知識MOMO就不贅述拉,不懂得朋友自己谷歌吧。我們專案的需求是在登入的時候使用HTTP請求,遊戲中其它的請求都用Socket請求,比如人物移動同步座標,同步關卡等等。

1.Socket

         Socket不要寫在指令碼上,如果寫在指令碼上游戲場景一旦切換,那麼這條指令碼會被釋放掉,Socket會斷開連線。場景切換完畢後需要重新在與伺服器建立Socket連線,這樣會很麻煩。所以我們需要把Socket寫在一個單例的類中,不用繼承MonoBehaviour。這個例子我模擬一下,主角在遊戲中移動,時時向服務端傳送當前座標,當伺服器返回同步座標時角色開始同步服務端新角色座標。

Socket在傳送訊息的時候採用的是位元組陣列,也就是說無論你的資料是 int float short object 都會將這些資料型別先轉換成byte[] , 目前在處理髮送的地方我使用的是資料包,也就是把(角色座標)結構體object轉換成byte[]傳送, 這就牽扯一個問題, 如何把結構體轉成位元組陣列, 如何把位元組陣列迴轉成結構體。請大家接續閱讀,答案就在後面,哇咔咔。

直接上程式碼

JFSocket.cs 該單例類不要繫結在任何物件上

[程式碼]:

  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System;  
  4. using System.Threading;  
  5. using System.Text;  
  6. using System.Net;  
  7. using System.Net.Sockets;  
  8. using System.Collections.Generic;  
  9. using System.IO;  
  10. using System.Runtime.InteropServices;  
  11. using System.Runtime.Serialization;  
  12. using System.Runtime.Serialization.Formatters.Binary;  
  13. publicclass JFSocket  
  14. {  
  15.     //Socket客戶端物件
  16.     private Socket clientSocket;  
  17.     //JFPackage.WorldPackage是我封裝的結構體,
  18.     //在與伺服器互動的時候會傳遞這個結構體
  19.     //當客戶端接到到伺服器返回的資料包時,我把結構體add存在連結串列中。
  20.     public List<JFPackage.WorldPackage> worldpackage;  
  21.     //單例模式
  22.     privatestatic JFSocket instance;  
  23.     publicstatic JFSocket GetInstance()  
  24.     {  
  25.         if (instance == null)  
  26.         {  
  27.             instance = new JFSocket();  
  28.         }  
  29.         return instance;  
  30.      }        
  31.     //單例的建構函式
  32.     JFSocket()  
  33.     {  
  34.         //建立Socket物件, 這裡我的連線型別是TCP
  35.         clientSocket = new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);  
  36.         //伺服器IP地址
  37.         IPAddress ipAddress = IPAddress.Parse ("192.168.1.100");  
  38.         //伺服器埠
  39.         IPEndPoint ipEndpoint = new IPEndPoint (ipAddress, 10060);  
  40.         //這是一個非同步的建立連線,當連線建立成功時呼叫connectCallback方法
  41.         IAsyncResult result = clientSocket.BeginConnect (ipEndpoint,new AsyncCallback (connectCallback),clientSocket);  
  42.         //這裡做一個超時的監測,當連線超過5秒還沒成功表示超時
  43.         bool success = result.AsyncWaitHandle.WaitOne( 5000, true );  
  44.         if ( !success )  
  45.         {  
  46.             //超時
  47.             Closed();  
  48.             Debug.Log("connect Time Out");  
  49.         }else
  50.         {  
  51.             //與socket建立連線成功,開啟執行緒接受服務端資料。
  52.             worldpackage = new List<JFPackage.WorldPackage>();  
  53.             Thread thread = new Thread(new ThreadStart(ReceiveSorket));  
  54.             thread.IsBackground = true;  
  55.             thread.Start();  
  56.         }  
  57.     }  
  58.     privatevoid connectCallback(IAsyncResult asyncConnect)  
  59.     {  
  60.         Debug.Log("connectSuccess");  
  61.     }  
  62.     privatevoid ReceiveSorket()  
  63.     {  
  64.         //在這個執行緒中接受伺服器返回的資料
  65.         while (true)  
  66.         {   
  67.             if(!clientSocket.Connected)  
  68.             {  
  69.                 //與伺服器斷開連線跳出迴圈
  70.                 Debug.Log("Failed to clientSocket server.");  
  71.                 clientSocket.Close();  
  72.                 break;  
  73.             }  
  74.             try
  75.             {  
  76.                 //接受資料儲存至bytes當中
  77.                 byte[] bytes = newbyte[4096];  
  78.                 //Receive方法中會一直等待服務端回發訊息
  79.                 //如果沒有回發會一直在這裡等著。
  80.                 int i = clientSocket.Receive(bytes);  
  81.                 if(i <= 0)  
  82.                 {  
  83.                     clientSocket.Close();  
  84.                     break;  
  85.                 }     
  86.                 //這裡條件可根據你的情況來判斷。
  87.                 //因為我目前的專案先要監測包頭長度,
  88.                 //我的包頭長度是2,所以我這裡有一個判斷
  89.                 if(bytes.Length > 2)  
  90.                 {  
  91.                     SplitPackage(bytes,0);  
  92.                 }else
  93.                 {  
  94.                     Debug.Log("length is not  >  2");  
  95.                 }  
  96.              }  
  97.              catch (Exception e)  
  98.              {  
  99.                 Debug.Log("Failed to clientSocket error." + e);  
  100.                 clientSocket.Close();  
  101.                 break;  
  102.              }  
  103.         }  
  104.     }     
  105.     privatevoid SplitPackage(byte[] bytes , int index)  
  106.     {  
  107.         //在這裡進行拆包,因為一次返回的資料包的數量是不定的
  108.         //所以需要給資料包進行查分。
  109.         while(true)  
  110.         {  
  111.             //包頭是2個位元組
  112.             byte[] head = newbyte[2];  
  113.             int headLengthIndex = index + 2;  
  114.             //把資料包的前兩個位元組拷貝出來
  115.             Array.Copy(bytes,index,head,0,2);  
  116. 相關推薦

    Unity3D研究院C#使用SocketHTTP連線伺服器傳輸資料

    最近專案中需要使用HTTP與Socket,把自己這段時間學習的資料整理一下。有關Socket與HTTP的基礎知識MOMO就不贅述拉,不懂得朋友自己谷歌吧。我們專案的需求是在登入的時候使用HTTP請求,遊戲中其它的請求都用Socket請求,比如人物移動同步座標,同步關卡

    Unity3D 遊戲引擎C#使用SocketHTTP連接server數據傳輸

    tco 類型 oba connect asp bre amp 客戶 star 近期比較忙。有段時間沒寫博客拉。近期項目中須要使用HTTP與Socket。雨松MOMO把自己這段時間學習的資料整理一下。有關Socket與HTTP的基礎知識MOMO就不贅述拉,不懂得朋友自己

    客戶端服務端互動sockethttp協議的比較

    webservice是基於http協議的soap協議的封裝和補充,為的是提供一個公共穩定的介面。 區別: (1 )資料傳輸方式 1.1  socket傳輸的定義和其特點 所謂socket通常也稱作"套接字",實現伺服器和客戶端之間的物理連線,並進行資料傳輸,主要有udp和tcp兩個協議。socket處於網路

    Unity3D研究院非同步載入遊戲場景非同步載入遊戲資源進度條(三十一)

              非同步任務相信大家應該不會陌生,那麼本章內容MOMO將帶領大家學習Unity中的一些非同步任務。在同步載入遊戲場景的時候通常會使用方法 Application.LoadLevel(“yourScene”);  這句程式碼執行完畢後程序會幹什麼呢??如下圖所示,這是我隨便找了一個遊戲場景

    sockethttp的區別

    單獨 計算機 是否 tcp協議 操作 end 不定 請求 釋放 1、TCP連接 手機能夠使用聯網功能是因為手機底層實現了TCP/IP協議,可以使手機終端通過無線網絡建立TCP連接。TCP協議可以對上層網絡提供接口,使上層網絡數據的傳輸建立在“無差別”的網絡之上。 建立起

    Unity3D研究院將UI的點擊事件滲透下去(轉)

    一個 響應 http void ons cti ive down point 轉自 http://www.xuanyusong.com/archives/4241 處理UI還有3D模型的點擊推薦使用UGUI的這套事件系統,因為使用起來比較簡潔,不需要自己用代碼來發送射線

    Unity3d學習路-牧師魔鬼V2(動作分離版)

    Unity3d學習之路-牧師與魔鬼V2(動作分離版) 該版本改進的目的 把每個需要移動的遊戲物件的移動方法提取出來,建立一個動作管理器來管理不同的移動方法。 對於上一個版本,每一個可移動的遊戲物件的元件都有一個Move指令碼,當遊戲物件需要移動時

    UnityC#——委託事件,觀察者模式,貓和老鼠事例

    委託與事件,觀察者模式,貓和老鼠事例     在Unity遊戲開發中,我們經常需要在一個類中,呼叫另一個類中的方法,比如,當玩家進入到某個地方,敵人就開始攻擊玩家。這時就需要利用委託與事件,設計觀察者模式。 此處我們利用貓和老鼠來簡單描述: 程式碼如下: Ca

    Unity3D開發c#主導呼叫安卓功能

    公司一直沒有盈利專案,我們3d組要解散。我也一直在找工作。找工作真的太糟心了。我想進的公司都不要我,要我的公司我都不太滿意。其實我一直是想去想去做手遊的。唉,有些公司連面試的機會都不給。好生氣 哈哈。最近一直在等訊息,我一個博士師傅昨天讓我去做模擬方向。我也在糾結到底該怎麼選

    大白話系列C#委託事件講解(一)

    從序言中,大家應該對委託和事件的重要性有點了解了吧,雖然說我們現在還是能模糊,但是從我的大白話系列中,我會把這些概念說的通俗易懂的。首先,我們還是先說說委託吧,從字面上理解,只要是中國人應該都知道這個意思,除非委託2箇中文字不認識,舉個例子,小明委託小張去買車票。    &nbs

    大白話系列C#委託事件講解大結局

    今天是大白話系列之C#委託與事件講解的大結局,也是我們最關心的,在日常的MES系統程式設計中到底怎樣使用這樣的利器,其實我們每天都在使用事件,一個窗體,一個按鈕都包含這事件,只是很少用到自己寫的委託和事件,說白了不知道如何下手,也不知道在什麼樣的場景下應用。 用到事件的地方有很多,這次講解就ME

    大白話系列C#委託事件講解(二)

    什麼是事件?EVENT?點選事件?載入事件?一連串的模糊的概念衝擊著我們弱小的腦袋 那我們首先來看一下比較正統的感念吧: 事件是類在發生其關注的事情時用來提供通知的一種方式。 事件的發生一般都牽扯2個角色 事件發行者(Publisher):一個事件的發行者,也稱作是傳送者(sende

    Unity3D研究院MAC&Windows跨平臺解析Excel

    轉載註明出處:http://www.xuanyusong.com/archives/2429   Excel 和 ICSharpCode.SharpZipLib 是第三方開發包(後面我會附帶下載地址的), 這個兩個東西必須存在。這個開發包是跨平臺的,並且完全獨立不依賴微軟的那一套東

    Unity3D研究院MAC&Windows跨平臺解析Excel

    Excel 和 ICSharpCode.SharpZipLib 是第三方開發包(後面我會附帶下載地址的), 這個兩個東西必須存在。這個開發包是跨平臺的,並且完全獨立不依賴微軟的那一套東東。即時你的電腦中沒有安裝Excel也同樣是可以很好的解析 通過程式碼來解析U

    C socket 傳送HTTP簡單介紹

    HTTP請求頭部樣例: GET http://www.baidu.com/ HTTP/1.1 Accept: html/text Host: 220.181.6.175:80 Connection: Close 這是一個請求百度頁面的頭部。 屬性和值的命名中間用:和空格隔

    C socket 傳送HTTP請求

    HTTP請求頭部樣例: GET http://www.baidu.com/ HTTP/1.1 Accept: html/text Host: 220.181.6.175:80 Connection: Close 這是一個請求百度頁面的頭部。 屬性和值的命名中間用:和空格隔

    Unity3D研究院mac上從.ipa中提取unity3D遊戲資源(六十六)

    感謝今天某大神(既然是大神名子我當然要保密嘍)告訴我Disunity更新了,不然我還不知道。以前很多人都說用Disunity提取出了Unity3D資源,但是我在Mac上從來沒有成功過,一直在報錯。https://github.com/ata4/disunity/re

    Unity3D研究院Assetbundle的原理

            上面MOMO已經將Assetbundle 的使用原理大致介紹了一下 ,我們在談談移動平臺。指令碼不能更新是移動平臺下最大的傷,這就意味著開發者無法繞過App store和 google Play這種線上商店升級應用程式。唯一能做到的就是更新資源、舉個例子,遊戲中在處理版本升級時,一般會有個大

    Unity3D研究院Assetbundle的使用

    注意:在測試的時候把plateform不要設定成webplayer 這樣你會減少很多麻煩 1.建立Assetbundle          無論是模型資源還是UI資源,最好是先把他們放在Prefab中,然後在做成Assetbundle。我們以模型來舉例,A

    轉載 雨鬆MOMO 2014年07月16日 於 雨鬆MOMO程式研究院 發表 Unity3D研究院Time.timeScale、遊戲暫停(七十四)

    專案裡面一直在用Time.timeScale來做遊戲的 1倍 2倍整體加速,今天我仔細看了一下Time.timeScale才發現之前我理解錯了一些東西。 Time.timeScale可以控制Update 和LateUpdate 的執行速度,舉個例子說明一下。