Unity聊天室Tcp協議
阿新 • • 發佈:2018-11-05
客戶端unity指令碼
using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.UI; public class UIManager : MonoBehaviour { private string ipaddress = "192.168.3.35"; private int port = 7788; private Thread t; //建立一個執行緒方便管理 private byte[] data = new byte[1024]; private string message = "";//Text用來接收Message的容器 public Text text; //聊天框 public InputField textInput; //輸入框 private Socket clientSocket; // Use this for initialization void Start () { ConnectedToServer(); } // Update is called once per frame void Update () { if (message!=null&&message!="") { text.text += "\n" + message; message = "";//清空訊息 } } //和伺服器連線的方法 private void ConnectedToServer() { clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //發起連線 clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port)); //建立一個執行緒用來接收訊息 t = new Thread(ReceiveMeage); t.Start(); } /// <summary> /// 用來迴圈接收訊息 /// </summary> void ReceiveMeage() { while (true) { //判斷是否和伺服器連線 if (clientSocket.Connected==false) { break; } int length = clientSocket.Receive(data); message = Encoding.UTF8.GetString(data, 0, length); //text.text += "\n" + message; //unity不允許單獨的執行緒操縱unity元件 } } //UI介面傳送按鈕的方法 public void SendMessage(string message) { //字串轉成位元組陣列 byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.Send(data); //傳送到伺服器端 } //當按鈕點選的時候獲取文字框內的資訊 public void OnSendButtonClick() { string value = textInput.text; //得到文字框內的內容 SendMessage(value); //傳送完輸入框為空 textInput.text = ""; } //防止客戶端斷開連線伺服器一直接收訊息 private void OnDestroy() { clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close();//關閉連線 } }
伺服器端
using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using 聊天室伺服器端_tcp; namespace 聊天室伺服器端 { /// <summary> /// 用來跟客戶端做通訊 /// </summary> class Client { private Socket clientSocket; private Thread t; //方便管理執行緒 private byte[] data = new byte[1024];//資料容器,方便頻繁呼叫 public Client(Socket s) { clientSocket = s; //啟動一個執行緒 處理客戶端的資料接收 t = new Thread(ReceiveMessage); t.Start(); } private void ReceiveMessage() { //一直接收客戶端的資料 while (true) { //在接收資料之前,判斷一下Socket是否斷開 if (clientSocket.Poll(10, SelectMode.SelectRead))//判斷客戶端是否斷開連線 { clientSocket.Close(); break;//跳出迴圈 終止執行緒 } //當客戶端斷開連線時會一直接收訊息,所以要在客戶端做處理 int length = clientSocket.Receive(data); string message = Encoding.UTF8.GetString(data, 0, length); //伺服器接收到資料,要把這個資料分發到客戶端 //廣播這個訊息 Program.BroadCastMessage(message); Console.WriteLine("收到了訊息" + message); } } //--------------向多個客戶端傳送訊息------------------------ /// <summary> /// 傳送方法 /// </summary> /// <param name="message"></param> public void SendMessage(string message) { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.Send(data); } /// <summary> /// 判斷是否和客戶端斷開連線 /// </summary> public bool Connected { get { return clientSocket.Connected; }//返回這個Socket是否斷開連線 } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; using 聊天室伺服器端; /// <summary> /// 伺服器端 /// </summary> namespace 聊天室伺服器端_tcp { class Program { //建立一個空的集合存放連線過來的client物件,就可以知道伺服器和哪些客戶端建立了連線 static List<Client> clientList = new List<Client>(); /// <summary> /// 廣播訊息分發到各個客戶端 /// </summary> public static void BroadCastMessage(string message) { var notConnectedList = new List<Client>();//存放斷開連線的客戶端 foreach (var client in clientList) { if(client.Connected) //客戶端在連線狀態 client.SendMessage(message); else { //斷開連線的客戶端放到這個集合 notConnectedList.Add(client); } } //把斷開連線的客戶端從clientList中移除掉 foreach (var temp in notConnectedList) { clientList.Remove(temp);//移除 } } static void Main(string[] args) { Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.3.35"),7788)); tcpServer.Listen(100); Console.WriteLine("伺服器連線成功"); //--------------接收多個連線--------------- while (true) { Socket clientSocket = tcpServer.Accept(); Console.WriteLine("一個客戶端連線過來"); Client client = new Client(clientSocket);//把收發訊息的邏輯放到Client類裡處理 clientList.Add(client); } } } }