網路 TCP:與打電話類似,通知服務到位 UDP:與發簡訊類似,消息發出即可 IP和埠號是網路兩大重要成員 埠號(Port)分為知名埠號[0-1024,不開放)和動態埠號[1024,10000多,開放可用) 三次握手,四次揮手: unity網端簡單案例: 分為:綜合管理部分、客戶端和伺服器 ...
網路
TCP:與打電話類似,通知服務到位
UDP:與發簡訊類似,消息發出即可
IP和埠號是網路兩大重要成員
埠號(Port)分為知名埠號[0-1024,不開放)和動態埠號[1024,10000多,開放可用)
三次握手,四次揮手:
unity網端簡單案例:
分為:綜合管理部分、客戶端和伺服器
需要Socket作為媒介來進行交互
見代碼:
一、綜合管理部分:
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 using System;
8
9 //綜合管理部分
10 // 可以供客戶端和伺服器一塊使用
11 public class TcpSocket
12 {
13 private Socket socket;//當前實例化的套接字
14 private byte[] data;//socket上的數據
15 private bool isServer; //用來區分伺服器 還是客戶端
16
17 //構造TcpSocket
18 public TcpSocket(Socket socket,int dataLength, bool isServer)
19 {
20 this.socket = socket;
21 data = new byte[dataLength];
22 this.isServer = isServer;
23 }
24 // 接受----->客戶端
25 public void ClientReceive()
26 {
27 //data:數據緩存 0:接受位的偏移量 length
28 socket.BeginReceive(data,0,data.Length,SocketFlags.None,new AsyncCallback(ClientEndReceive),null);
29 }
30 public void ClientEndReceive(IAsyncResult ar)
31 {
32 int receiveLength = socket.EndReceive(ar); //數據的處理
33 string dataStr = System.Text.Encoding.UTF8.GetString(data,0, receiveLength); //把接受完畢的位元組數組轉化為 string類型
34 if (isServer)
35 { Debug.Log("伺服器接受到了:" + dataStr);
36 for (int i = 0; i < Server.Instance.clients.Count; i++) //伺服器要回什麼
37 {
38 if (Server.Instance.clients[i].ClientConnect())
39 {
40 Server.Instance.clients[i].ClientSeed(System.Text.Encoding.UTF8.GetBytes("伺服器回覆:"+ dataStr));
41 }
42 }
43 }else {
44 DataManager.Instance.Msg = dataStr;
45 Debug.Log("客戶端接受到了:" + dataStr);
46 }
47 }
48
49
50 // 發送---->客戶端發送給伺服器
51 public void ClientSeed(byte[] data)
52 {
53 socket.BeginSend(data,0, data.Length, SocketFlags.None,new AsyncCallback(ClientSeedEnd),null );
54 }
55
56 private void ClientSeedEnd(IAsyncResult ar)
57 {
58 socket.EndSend(ar);
59 }
60
61
62 //連接----客戶端與伺服器連接
63 public void ClientConnect(string ip,int port)
64 {
65 socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), port),new AsyncCallback(ClientEndConnect),null);
66 }
67 public void ClientEndConnect(IAsyncResult ar)
68 {
69 if (ar.IsCompleted) {
70 Debug.Log("連接成功");
71 }
72 socket.EndConnect(ar);
73 }
74
75 // 客戶端與伺服器是否連接
76
77 public bool IsClientConnect()
78 {
79 return socket.Connected;
80 }
81 //斷開連接
82 public void ClientClose()
83 {
84 if (socket!=null&& ISClientConnect())
85 {
86 socket.Close();
87 }
88 }
89
90 }
View Code
二、伺服器部分:
註意:回調函數AcceptClient只有當伺服器接受連接(連接成功了)才會被調用.
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 using System; 8 9 // 伺服器 10 11 public class Server : MonoBehaviour { 12 13 //單例伺服器,繼承Mono的 14 private static Server instance; 15 public static Server Instance 16 { 17 get { return instance; } 18 } 19 private void Awake() 20 { 21 instance = this; 22 } 23 //------------------------------------------------------------------------ 24 private Socket server;//定義一個伺服器 25 public List<TcpSocket> clients;//所有連接的客戶端 26 private bool isLoopAccept = true;//是否迴圈接受客戶端的請求 27 28 void Start () 29 { 30 //初始化伺服器socket 協議族 31 server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 32 server.Bind(new IPEndPoint(IPAddress.Any,10086));//綁定埠號 33 server.Listen(100); //可以監聽的客戶端數目 34 //------------------------------------------------------------------------ 35 //開闢一個線程 處理客戶端連接請求 線程要暫停需用listenThread.Abort(); 36 Thread listenThread = new Thread(ReceiveClient); 37 listenThread.Start(); //開啟線程 38 listenThread.IsBackground = true; //後臺運行 39 //------------------------------------------------------------------------ 40 //初始化連接的客戶端 41 clients = new List<TcpSocket>(); 42 43 } 44 45 // 持續處理 接受客戶端連接的請求 46 private void ReceiveClient() 47 { 48 while (isLoopAccept) 49 { 50 server.BeginAccept(AcceptClient,null); //開始接受客戶端連接請求 51 Debug.Log("檢測客戶端連接中....."); 52 Thread.Sleep(1000);//每隔1s檢測 有沒有連接我 53 } 54 } 55 // 客戶端連接成功之後回調 56 private void AcceptClient(IAsyncResult ar) 57 { 58 //連接成功後處理該客戶 59 Socket client = server.EndAccept(ar); 60 TcpSocket clientSocket = new TcpSocket(client,1024,true); 61 clients.Add(clientSocket); 62 Debug.Log("連接成功"); 63 } 64 //關閉項目終止線程,停止伺服器. 65 private void OnApplicationQuit() 66 { 67 listenThread.Abort(); 68 listenThread.IsBackground = true;//關閉線程 69 } 70 }View Code
三、客戶端部分:
using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; using System; using UnityEngine; using UnityEngine.UI; //客戶端 public class Client : MonoBehaviour { public InputField input; public Text receiveText; TcpSocket tcpClient; Socket client; void Start () { //註冊監聽事件 receiveText = GameObject.Find("ReceiveText").GetComponent<Text>(); tcpClient = new TcpSocket(client,1024,false);//初始化綜合處理器 client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化客戶端 } void Update () { if (tcpClient != null && tcpClient.IsClientConnect())//如果客戶端不為空且客戶端已連接 { tcpClient.ClientReceive();//執行綜合管理器中的ClientReceive() } receiveText.text = DataManager.Instance.Msg; } public void OnClickConnectBtn()//客戶端向伺服器開始連接輸入(IP和埠號)按鈕事件 { if (!tcpClient.IsClientConnect()) { tcpClient.ClientConnect("10.50.6.129",10086); } } public void OnClickToSendServer()//客戶端向伺服器發送文本消息按鈕事件 { if (tcpClient != null && tcpClient.IsClientConnect() && !String.IsNullOrEmpty(input.text)) { tcpClient.ClientSeed(System.Text.Encoding.UTF8.GetBytes(input.text)); input.text = ""; } } private void OnApplicationQuit()//關閉項目,退出伺服器連接 { if (tcpClient != null && tcpClient.ClientConnect()) { tcpClient.ClientClose(); } } }View Code