2017年11月10日 星期五

Unity內使用UDP方式來進行連線和傳送資料

網路連線、TCP和UDP那些大道理就不講了,不懂的人建議在看這篇前先去觀看一下相關的定義。

這邊簡單來講,有兩個程式分別在兩台電腦上,希望可以透過網路來互相傳遞資料,因此其中之一的作法便是透過UDP方式來進行傳送資料。

可以分開寫成兩個程式,也可以全部都寫在同一個程式內,然後自己再另外寫可選擇當Server或Client的程式。我是常常寫在一個程式內,然後再外加可選擇的方式來定義Server和Client。

所以以下單純來看Script,有Server和Client的Script。

先來看當Client的Script:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Net;
  5. using System.Net.Sockets;
  6.  
  7. public class ClientController : MonoBehaviour {
  8.  
  9.     private IPEndPoint ipEndPoint;
  10.     private UdpClient udpClient;
  11.     private byte[] sendByte;
  12.  
  13.     void Start ()
  14.     {
  15.         ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);
  16.         udpClient = new UdpClient();
  17.         SendUDPData("這是要傳送的資料");
  18.     }
  19.  
  20.     void Update ()
  21.     {
  22.  
  23.     }
  24.  
  25.     void SendUDPData(string tempData)
  26.     {
  27.         sendByte = System.Text.Encoding.UTF8.GetBytes(tempData);
  28.         udpClient.Send(sendByte, sendByte.Length, ipEndPoint);
  29.     }
  30. }
這邊範例的IPAddress是使用Local端,當然也可以使用網際網路的網址。
仔細看程式碼的話,便會知道Client單方面的向Server發送了資料。

再來看當Server的Script:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Threading;
  7.  
  8. public class ServerController : MonoBehaviour {
  9.  
  10.     private IPEndPoint ipEndPoint;
  11.     private UdpClient udpClient;
  12.     private Thread receiveThread;
  13.     private byte[] receiveByte;
  14.     private string receiveData = "";
  15.  
  16.     void Start ()
  17.     {
  18.         ipEndPoint = new IPEndPoint(IPAddress.Any, 5555);
  19.         udpClient = new UdpClient(ipEndPoint.Port);
  20.  
  21.         receiveThread = new Thread(ReceiveData);
  22.         receiveThread.IsBackground = true;
  23.         receiveThread.Start();
  24.     }
  25.  
  26.     void Update ()
  27.     {
  28.  
  29.     }
  30.  
  31.     void ReceiveData()
  32.     {
  33.         while (true)
  34.         {
  35.             receiveByte = udpClient.Receive(ref ipEndPoint);
  36.             receiveData = System.Text.Encoding.UTF8.GetString(receiveByte);
  37.  
  38.             Debug.Log("接收到:" + receiveData);
  39.         }
  40.     }
  41.  
  42.     private void OnDisable()
  43.     {
  44.         udpClient.Close();
  45.         receiveThread.Join();
  46.         receiveThread.Abort();
  47.     }
  48.  
  49.     private void OnApplicationQuit()
  50.     {
  51.         receiveThread.Abort();
  52.     }
  53. }
可以看到Server的接收是寫在Thread裡面,如果不另外開執行緒來進行資料的監聽接收,那程式會卡死在那不會動,這點很重要。

關閉程式時,一定要徹底關閉這個Thread;不然即使程式關閉了,這個Thread還會依然持續執行,相關資訊可自行上網查詢。

這裡寫的是Client發送資料給Server的單方向範例,當然也可以Server發送資料給Client,寫法完全一樣。

因為我想要最直接呈現UDP的寫法,所以相關安全措施大都沒有加入,像Try catch等這些安全機制其實是應該要加入的。

1 則留言:

  1. 想請問,有需要另外關防火牆之類的嗎?
    因為我使用了兩台電腦,卻無法找到伺服器端

    回覆刪除