認識socket
在計算機通信領域,socket 被翻譯為“套接字”,它是計算機之間進行通信的一種約定或一種方式。通過 socket 這種約定,一台計算機可以接收其他計算機的數據,也可以向其他計算機發送數據socket起源於Unix,而Unix/Linux基本哲學之一就是“一切皆文件”,都可以用“打開open –> 讀寫write/read –> 關閉close”模式來操作。我的理解就是Socket就是該模式的一個實現:即socket是一種特殊的文件,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉)。Socket()函數返回一個整型的Socket描述符,隨后的連接建立、數據傳輸等操作都是通過該Socket實現的。
實現socket通訊,需要兩個部分才能進行數據通訊。
1,客戶端請求連接
2,服務器響應
服務端
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using System.Net.Sockets;//需要引用socket命名空間 5 using System.Net; 6 using System.Linq; 7 using System.Text; 8 using System.Threading; 9 10 public class net : MonoBehaviour 11 { 12 // Start is called before the first frame update 13 void Start() 14 { 15 openServer(); 16 } 17 18 // Update is called once per frame 19 void Update() 20 { 21 22 } 23 24 /// <summary> 25 /// 打開鏈接 26 /// </summary> 27 void openServer() 28 { 29 try 30 { 31 IPAddress pAddress = IPAddress.Parse("127.0.0.1"); 32 IPEndPoint pEndPoint = new IPEndPoint(pAddress, 52315); 33 Socket socket_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 34 socket_server.Bind(pEndPoint); 35 socket_server.Listen(5);//設置最大連接數 36 Debug.Log("監聽成功"); 37 //創建新線程執行監聽,否則會阻塞UI,導致unity無響應 38 Thread thread = new Thread(listen); 39 thread.IsBackground = true; 40 thread.Start(socket_server); 41 } 42 catch (System.Exception) 43 { 44 45 throw; 46 } 47 } 48 /// <summary> 49 /// 監聽 50 /// </summary> 51 Socket socketSend; 52 void listen(object o) 53 { 54 try 55 { 56 Socket socketWatch = o as Socket; 57 while (true) 58 { 59 socketSend = socketWatch.Accept(); 60 Debug.Log(socketSend.RemoteEndPoint.ToString() + ":" + "連接成功"); 61 62 Thread r_thread = new Thread(Received); 63 r_thread.IsBackground = true; 64 r_thread.Start(socketSend); 65 } 66 } 67 catch (System.Exception) 68 { 69 70 throw; 71 } 72 } 73 /// <summary> 74 /// 獲取消息 75 /// </summary> 76 /// <param name="o"></param> 77 void Received(object o) 78 { 79 try 80 { 81 Socket socketSend = o as Socket; 82 while (true) 83 { 84 byte[] buffer = new byte[1024]; 85 int len = socketSend.Receive(buffer); 86 if (len == 0) break; 87 string str = Encoding.UTF8.GetString(buffer, 0, len); 88 Debug.Log("服務器打印客戶端返回消息:" + socketSend.RemoteEndPoint + ":" + str); 89 Send("我收到了"); 90 } 91 } 92 catch (System.Exception) 93 { 94 95 throw; 96 } 97 } 98 /// <summary> 99 /// 發送消息 100 /// </summary> 101 /// <param name="msg"></param> 102 void Send(string msg) 103 { 104 byte[] buffer = Encoding.UTF8.GetBytes(msg); 105 socketSend.Send(buffer); 106 } 107 }
客戶端
1 using UnityEngine; 2 using UnityEngine.UI; 3 using System.Net; 4 using System.Net.Sockets;//引入socket命名空間 5 using System.Threading; 6 using System.Text; 7 using UnityEngine.SceneManagement; 8 9 public class net : MonoBehaviour 10 { 11 //添加兩個按鈕用於發送數據和關閉連接 12 public Button sen; 13 public Button col; 14 //輸入文本 15 public InputField inputText; 16 // Start is called before the first frame update 17 void Start() 18 { 19 sen.onClick.AddListener(send_smg);//發送 20 col.onClick.AddListener(close_btnClick);//關閉 21 } 22 23 // Update is called once per frame 24 void Update() 25 { 26 27 } 28 29 public void send_smg() 30 { 31 Send(inputText.text); 32 } 33 public void close_btnClick() 34 { 35 close(); 36 } 37 38 /// <summary> 39 /// 連接服務器 40 /// </summary> 41 static Socket socket_client; 42 public static void ConnectServer() 43 { 44 try 45 { 46 IPAddress pAddress = IPAddress.Parse("127.0.0.1"); 47 IPEndPoint pEndPoint = new IPEndPoint(pAddress, 52315); 48 socket_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 49 socket_client.Connect(pEndPoint); 50 Debug.Log("連接成功"); 51 //創建線程,執行讀取服務器消息 52 Thread c_thread = new Thread(Received); 53 c_thread.IsBackground = true; 54 c_thread.Start(); 55 } 56 catch (System.Exception) 57 { 58 59 Debug.Log("IP端口號錯誤或者服務器未開啟"); 60 } 61 } 62 63 /// <summary> 64 /// 讀取服務器消息 65 /// </summary> 66 public static void Received() 67 { 68 while (true) 69 { 70 try 71 { 72 byte[] buffer = new byte[1024]; 73 int len = socket_client.Receive(buffer); 74 if (len == 0) break; 75 string str = Encoding.UTF8.GetString(buffer, 0, len); 76 Debug.Log("客戶端打印服務器返回消息:" + socket_client.RemoteEndPoint + ":" + str); 77 } 78 catch (System.Exception) 79 { 80 81 throw; 82 } 83 84 } 85 } 86 /// <summary> 87 /// 發送消息 88 /// </summary> 89 /// <param name="msg"></param> 90 public static void Send(string msg) 91 { 92 try 93 { 94 byte[] buffer = new byte[1024]; 95 buffer = Encoding.UTF8.GetBytes(msg); 96 socket_client.Send(buffer); 97 } 98 catch (System.Exception) 99 { 100 101 Debug.Log("未連接"); 102 } 103 } 104 /// <summary> 105 /// 關閉連接 106 /// </summary> 107 public static void close() 108 { 109 try 110 { 111 socket_client.Close(); 112 Debug.Log("關閉客戶端連接"); 113 SceneManager.LoadScene("control"); 114 } 115 catch (System.Exception) 116 { 117 Debug.Log("未連接"); 118 } 119 } 120 }
將服務器腳本和客戶端腳本分別掛載在各自對應unity對象上即可實現socket tcp連接通訊。