好用的局域网内的网络控制器,稍作更改可连接互联网
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();
}