好用的局域网内的网络控制器,稍作更改可连接互联网
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using LitJson;
using UnityEngine;
using Random = UnityEngine.Random;public struct UdpMessage
{public string format;public string usingName;public Dictionary<string,string> getString;public Dictionary<string, List<string>> getStringList;public Dictionary<string, Dictionary<string, string>> getStringDictionary;public UdpMessage(string format,string usingName){this.format = format;this.usingName = usingName;getString = new Dictionary<string, string>();getStringList = new Dictionary<string, List<string>>();getStringDictionary = new Dictionary<string, Dictionary<string, string>>();}public UdpMessage SetString(Dictionary<string,string> setString){getString = setString;return this;}public UdpMessage SetStringList(Dictionary<string, List<string>> setStringList){getStringList = setStringList;return this;}public UdpMessage SetStringDictionary(Dictionary<string, Dictionary<string, string>> setStringDictionary){getStringDictionary = setStringDictionary;return this;}
}public struct HandleMessage
{public UdpMessage message;public IPEndPoint endPoint;public HandleMessage(UdpMessage message,IPEndPoint endPoint){this.message = message;this.endPoint = endPoint;}
}public class GameNetController
{private static GameNetController main;public static GameNetController Main{get{if (main == null){main = new GameNetController();UnitManager.Main.GameNetOpen();}return main;}}private UdpClient severClient;private Thread messageThread;public bool isLocalPlayer = true;public Dictionary<string, List<HandleMessage>> messageList = new Dictionary<string, List<HandleMessage>>();public Dictionary<string, IPEndPoint> allClient = new Dictionary<string, IPEndPoint>();public Dictionary<string, Action<UdpMessage,IPEndPoint>> severAction = new Dictionary<string, Action<UdpMessage,IPEndPoint>>();public Dictionary<string, Action<UdpMessage,IPEndPoint>> clientAction = new Dictionary<string, Action<UdpMessage,IPEndPoint>>();public void SeverInit(){isLocalPlayer = false;severClient = new UdpClient(new IPEndPoint(IPAddress.Any, int.Parse(UnitManager.Main.GetLocalText("连接端口"))));messageThread = new Thread(SeverListenMessage);messageThread.Start();}private IPEndPoint mainPoint, severPoint;private UdpClient mainClient;public void ClientInit(){isLocalPlayer = false;mainPoint = new IPEndPoint(IPAddress.Any, Random.Range(20000,60000));severPoint = new IPEndPoint(IPAddress.Parse(UnitManager.Main.GetLocalText("管理员地址")), int.Parse(UnitManager.Main.GetLocalText("连接端口")));mainClient = new UdpClient(mainPoint);messageThread = new Thread(ClientListenMessage);messageThread.Start();}private byte[] bytes;private IPEndPoint endPoint;private UdpMessage message;private Dictionary<string, string> getPacket = new Dictionary<string, string>();void ClientListenMessage(){while (true){bytes = mainClient.Receive(ref endPoint);string getStr = Encoding.UTF8.GetString(bytes);if (getStr.Contains("packet")){if (!getPacket.ContainsKey(getStr.Split('^')[0].Split(':')[1])){getPacket.Add(getStr.Split('^')[0].Split(':')[1],"");}getPacket[getStr.Split('^')[0].Split(':')[1]] += getStr.Split('^')[1];if(getStr.Split('^')[0].Split(':')[0] == "packet"){continue;}if(getStr.Split('^')[0].Split(':')[0] == "packetEnd"){getStr = getPacket[getStr.Split('^')[0].Split(':')[1]];getPacket.Remove(getStr.Split('^')[0].Split(':')[1]);}}message = JsonMapper.ToObject<UdpMessage>(getStr);if (!messageList.ContainsKey(message.format)){messageList.Add(message.format,new List<HandleMessage>());}messageList[message.format].Add(new HandleMessage(message,endPoint));}}void SeverListenMessage(){while (true){ bytes = severClient.Receive(ref endPoint);string getStr = Encoding.UTF8.GetString(bytes);if (getStr.Contains("packet")){Debug.LogError("接收到数据包" + getStr.Split('^')[0]);if (!getPacket.ContainsKey(getStr.Split('^')[0].Split(':')[1])){getPacket.Add(getStr.Split('^')[0].Split(':')[1],"");}getPacket[getStr.Split('^')[0].Split(':')[1]] += getStr.Split('^')[1];if(getStr.Split('^')[0].Split(':')[0] == "packet"){Debug.LogError("接收到过度数据包" + getStr.Split('^')[0]);continue;}if(getStr.Split('^')[0].Split(':')[0] == "packetEnd"){Debug.LogError("接收到终结数据包" + getStr.Split('^')[0]);getStr = getPacket[getStr.Split('^')[0].Split(':')[1]];getPacket.Remove(getStr.Split('^')[0].Split(':')[1]);}}message = JsonMapper.ToObject<UdpMessage>(getStr);if (!messageList.ContainsKey(message.format)){messageList.Add(message.format,new List<HandleMessage>());}messageList[message.format].Add(new HandleMessage(message,endPoint));if (message.usingName != "" && !allClient.ContainsKey(message.usingName)){allClient.Add(message.usingName, endPoint);}if (message.usingName != "" && allClient.ContainsKey(message.usingName)){allClient[message.usingName] = endPoint;}}}public void ClientSendMessage(UdpMessage message){string str = JsonMapper.ToJson(message);if (str.Length > 10000){int number = Random.Range(0, int.MaxValue);string getStr = "";List<string> strList = new List<string>();while (true){if (str.Length > 10000){getStr = "packet:" + number + "^";getStr += str.Substring(0, 10000);strList.Add(getStr);str = str.Remove(0, 10000);}else{getStr = "packetEnd:" + number + "^";getStr += str.Substring(0, str.Length);strList.Add(getStr);break;}}for (int i = 0; i < strList.Count; i++){byte[] bytes = Encoding.UTF8.GetBytes(strList[i]);UnitManager.Main.Wait(i*0.1f, () =>{try{mainClient.Send(bytes, bytes.Length, severPoint);}catch (Exception e) { Debug.LogError(e); }});}}else{bytes = Encoding.UTF8.GetBytes(str);try{mainClient.Send(bytes, bytes.Length, severPoint);}catch (Exception e) { Debug.LogError(e); }}}public void SeverSendMessage(UdpMessage message){string str = JsonMapper.ToJson(message);if (str.Length > 10000){int number = Random.Range(0, int.MaxValue);string getStr = "";List<string> strList = new List<string>();while (true){if (str.Length > 10000){getStr = "packet:" + number + "^";getStr += str.Substring(0, 10000);strList.Add(getStr);str = str.Remove(0, 10000);}else{getStr = "packetEnd:" + number + "^";getStr += str.Substring(0, str.Length);strList.Add(getStr);break;}}for (int i = 0; i < strList.Count; i++){byte[] bytes = Encoding.UTF8.GetBytes(strList[i]);UnitManager.Main.Wait(i*0.1f, () =>{foreach (var client in allClient){try{severClient.Send(bytes, bytes.Length, client.Value);}catch (Exception e) { Debug.LogError(e); }}});}}else{bytes = Encoding.UTF8.GetBytes(str);foreach (var client in allClient){try{severClient.Send(bytes, bytes.Length, client.Value);}catch (Exception e) { Debug.LogError(e); }}}}public void SeverSendMessage(IPEndPoint endPoint,UdpMessage message){string str = JsonMapper.ToJson(message);if (str.Length > 10000){int number = Random.Range(0, int.MaxValue);string getStr = "";List<string> strList = new List<string>();while (true){if (str.Length > 10000){getStr = "packet:" + number + "^";getStr += str.Substring(0, 10000);strList.Add(getStr);str = str.Remove(0, 10000);}else{getStr = "packetEnd:" + number + "^";getStr += str.Substring(0, str.Length);strList.Add(getStr);break;}}for (int i = 0; i < strList.Count; i++){byte[] bytes = Encoding.UTF8.GetBytes(strList[i]);UnitManager.Main.Wait(i*0.1f, () =>{try{severClient.Send(bytes, bytes.Length, endPoint);}catch (Exception e) { Debug.LogError(e); }});}}else{bytes = Encoding.UTF8.GetBytes(str);try{severClient.Send(bytes, bytes.Length, endPoint);}catch (Exception e) { Debug.LogError(e); }}}public void SeverSendMessage(List<string> sendNames,UdpMessage message){foreach (string sendName in sendNames){SeverSendMessage(allClient[sendName],message);}}
}
同时找一个继承MonoBehaviour的类添加一段Update来处理接收到的数据
private bool gameNetOpen;public void GameNetOpen(){gameNetOpen = true;}private void Update(){if(!gameNetOpen){return;}if(GameNetController.Main.messageList.Count == 0){return;}foreach (var message in GameNetController.Main.messageList){if (GameNetController.Main.severAction.ContainsKey(message.Key)){foreach (HandleMessage handleMessage in message.Value){try{GameNetController.Main.severAction[message.Key](handleMessage.message,handleMessage.endPoint);}catch{}}GameNetController.Main.messageList.Remove(message.Key);return;}if (GameNetController.Main.clientAction.ContainsKey(message.Key)){foreach (HandleMessage handleMessage in message.Value){try{GameNetController.Main.clientAction[message.Key](handleMessage.message,handleMessage.endPoint);}catch{}}GameNetController.Main.messageList.Remove(message.Key);return;}}GameNetController.Main.messageList.Clear();}