Unity使用C#實現簡單Scoket連線及服務端與客戶端通訊
阿新 • • 發佈:2019-01-24
簡介:
網路程式設計是個很有意思的事情,偶然翻出來很久之前剛開始看Socket的時候寫的一個例項,貼出來吧
Unity中實現簡單的Socket連線,c#中提供了豐富的API,直接上程式碼。
服務端程式碼:
Thread connectThread;//當前服務端監聽子執行緒 public string address;//當前地址 public int port;//當前本地埠 TcpClient romoteClient;//遠端客戶端 // Use this for initialization void Start() { connectThread = new Thread(InitServerSocket); connectThread.Start(); } /// <summary> /// 例項化服務端Socket /// </summary> public void InitServerSocket() { int bufferSize = 8192;//緩衝區大小 IPAddress ip = IPAddress.Parse(address); //新建TCP連線,並開啟監聽子執行緒 TcpListener tcpListener = new TcpListener(ip, port); tcpListener.Start(); Debug.Log("服務端-->客戶端完成,開啟tcp連線監聽"); //如果有遠端客戶端連線,此時得到其物件用於通訊 romoteClient = tcpListener.AcceptTcpClient(); Debug.Log("客戶端連線開始 本地地址埠: " + romoteClient.Client.LocalEndPoint + " 遠端客戶端地址埠: " + romoteClient.Client.RemoteEndPoint); NetworkStream stream = romoteClient.GetStream(); do { try { //獲取與客戶端連線資料 byte[] buffer = new byte[bufferSize]; int byteRead = stream.Read(buffer, 0, bufferSize); if (byteRead == 0) { Debug.Log("客戶端斷開"); break; } string msg = Encoding.UTF8.GetString(buffer, 0, byteRead); Debug.Log("接收到客戶端的資料: " + msg + " 資料長度: " + byteRead + "位元組"); } catch (Exception ex) { Debug.Log("客戶端異常: " + ex.Message); //客戶端出現異常或者斷開的時候,關閉執行緒防止溢位 tcpListener.Stop(); break; } } while (true); } /// <summary> /// 伺服器端根據當前連線的遠端客戶端傳送訊息 /// </summary> public void SendMessageToClient() { if (romoteClient != null) { romoteClient.Client.Send(Encoding.UTF8.GetBytes("Hello Client ,This is Server!")); } } /// <summary> /// 銷燬時關閉監聽執行緒及連線 /// </summary> void OnDestroy() { if (romoteClient != null) romoteClient.Close(); if (connectThread != null) connectThread.Abort(); }
客戶端程式碼:
public string serverAddress;//伺服器地址 public int port;//伺服器埠 private TcpClient localClient;//當前tcp客戶端 private Thread receiveThread;//接收伺服器訊息執行緒 private byte[] resultBuffer = new byte[1024];//伺服器返回流位元組 private string resultStr;//伺服器返回字串 void Start() { //連線至服務端 InitClientSocket(); } /// <summary> /// 銷燬時操作 /// </summary> private void OnDestroy() { if (localClient != null) localClient.Close(); if (receiveThread != null) receiveThread.Abort(); } /// <summary> /// 客戶端例項化Socket連線 /// </summary> private void InitClientSocket() { localClient = new TcpClient(); try { //當前客戶端連線的伺服器地址與遠端埠 localClient.Connect(IPAddress.Parse(serverAddress), port); //開始接收伺服器訊息子執行緒 receiveThread = new Thread(SocketReceiver); receiveThread.Start(); Debug.Log("客戶端-->服務端完成,開啟接收訊息執行緒"); } catch (Exception ex) { Debug.Log("客戶端連線伺服器異常: " + ex.Message); } Debug.Log("連線到伺服器 本地地址埠:" + localClient.Client.LocalEndPoint + " 遠端伺服器埠:" + localClient.Client.RemoteEndPoint); } /// <summary> /// 客戶端傳送訊息到伺服器 /// </summary> private void SendMessageToServer() { try { string clientStr = "Hello Server, This is Client!"; //獲取當前客戶端的流物件,然後將要傳送的字串轉化為byte[]寫入傳送 NetworkStream stream = localClient.GetStream(); byte[] buffer = Encoding.UTF8.GetBytes(clientStr); stream.Write(buffer, 0, buffer.Length); } catch (Exception ex) { Debug.Log("傳送訊息時伺服器產生異常: " + ex.Message); } } /// <summary> /// 客戶端檢測收到伺服器資訊子執行緒 /// </summary> private void SocketReceiver() { if (localClient != null) { while (true) { if (localClient.Client.Connected == false) break; //在迴圈中, localClient.Client.Receive(resultBuffer); resultStr = Encoding.UTF8.GetString(resultBuffer); Debug.Log("客戶端收到伺服器訊息 : " + resultStr); } } }
此時,面板填入服務端的地址及埠,執行服務端,再執行客戶端,客戶端點擊發送訊息,伺服器收到訊息,服務端傳送訊息後,客戶端收到訊息。本人是在兩臺機器上進行測試,Debug如下:
服務端:
客戶端:
注意事項:
1.服務端和客戶端的地址不要寫錯
2.服務端的埠確保未被佔用
3.在進行通訊的時候,要保持字串編碼格式一致
4.子執行緒的生命週期,記得銷燬,為了保證在主執行緒銷燬同時銷燬子執行緒可以使用thread.IsBackground = true