之前寫了一篇。 發完之後第二天實際應用到游戲之後還是發現了一些小毛病。 比如網路模塊有重覆使用(多對象)的情況。所以將靜態類該成了普通類。 比如安卓下會有些異常出現導致游戲邏輯不正常。所以網路相關的函數有些加了try塊。 然後發現寫入固定ip的方式根本不適合區域網。於是加了udp做的廣播系統,用以服 ...
之前寫了一篇。
發完之後第二天實際應用到游戲之後還是發現了一些小毛病。
比如網路模塊有重覆使用(多對象)的情況。所以將靜態類該成了普通類。
比如安卓下會有些異常出現導致游戲邏輯不正常。所以網路相關的函數有些加了try塊。
然後發現寫入固定ip的方式根本不適合區域網。於是加了udp做的廣播系統,用以伺服器和客戶端查找ip。
udp廣播部分和tcp不一樣。因為沒有連接,所以socket不需要shutdown。我在這裡吃了一虧才知道。
別的沒什麼修改。貼上修正和擴展之後的代碼。
有緣之人自取。唯一要求,如果你發現代碼有錯,或者有可以提升性能的地方請留言告知。
另:因為這是為區域網設計的,所以網路部分框架以及鎖的應用寫得很隨意,如果需要擴展至千人萬人級的承載,請自行修改。
基礎類(base)
ClientMsgUnPack.cs 伺服器tcp部分用以解包的對象
1 using UnityEngine; 2 /* 3 * 通信協議 4 * 消息頭前2位元組保存當前消息長度 5 * 後面跟4位元組表示消息ID 6 * 再後面是消息實質內容 7 */ 8 9 namespace LanSocket 10 { 11 class ClientMsgUnPack : MsgUnPack 12 { 13 long m_UserID; 14 public ClientMsgUnPack() 15 { 16 m_UserID = -1; 17 } 18 19 public ClientMsgUnPack(byte[] mBuff, ushort len, int userID) 20 { 21 m_UserID = userID; 22 UnPack(mBuff, len); 23 } 24 25 public ClientMsgUnPack(byte[] mBuff, ushort offset, ushort len, int userID) 26 { 27 m_UserID = userID; 28 UnPack(mBuff, offset, len); 29 } 30 31 public long GetUserID() 32 { 33 return m_UserID; 34 } 35 36 public void SetUserID(long userID) 37 { 38 m_UserID = userID; 39 } 40 } 41 }ClientMsgUnPack.cs
EventDispath.cs 事件分發,有兩個類,分別對應伺服器和客戶端,主要就是參數不同
1 using UnityEngine; 2 using System.Collections; 3 using System.Collections.Generic; 4 5 delegate void ServerEventDelagate(LanSocket.ClientMsgUnPack msg); 6 7 class EventNode 8 { 9 public int m_EventID; 10 public LanSocket.ClientMsgUnPack msg; 11 } 12 13 class EventDispathBase 14 { 15 public static int g_MaxEventNum = 300; 16 } 17 18 class ServerEventDispath : EventDispathBase 19 { 20 List<ServerEventDelagate>[] m_Event; 21 Queue<EventNode> m_EventQueue; 22 public ServerEventDispath() 23 { 24 m_Event = new List<ServerEventDelagate>[g_MaxEventNum]; 25 m_EventQueue = new Queue<EventNode>(); 26 } 27 28 public void RegistEvent(int eventID, ServerEventDelagate func) 29 { 30 if(null == m_Event[eventID]) 31 { 32 m_Event[eventID] = new List<ServerEventDelagate>(); 33 } 34 m_Event[eventID].Add(func); 35 } 36 37 public void AddEvent(EventNode eventNode) 38 { 39 m_EventQueue.Enqueue(eventNode); 40 } 41 42 public void Proccess() 43 { 44 if (0 != m_EventQueue.Count) 45 { 46 EventNode mCur = m_EventQueue.Dequeue(); 47 if (null == m_Event[mCur.m_EventID]) 48 { 49 MonoBehaviour.print("event ID: "+ mCur.m_EventID+" is null"); 50 } 51 else 52 { 53 List<ServerEventDelagate> curEventDelagate = m_Event[mCur.m_EventID]; 54 for(int i = 0 ; i < curEventDelagate.Count ; ++i) 55 { 56 curEventDelagate[i](mCur.msg); 57 } 58 } 59 } 60 } 61 } 62 63 64 delegate void ClientEventDelagate(LanSocket.MsgUnPack msg); 65 class ClientEventDispath : EventDispathBase 66 { 67 List<ClientEventDelagate>[] m_Event; 68 Queue<EventNode> m_EventQueue; 69 public ClientEventDispath() 70 { 71 m_Event = new List<ClientEventDelagate>[g_MaxEventNum]; 72 m_EventQueue = new Queue<EventNode>(); 73 } 74 75 public void RegistEvent(int eventID, ClientEventDelagate func) 76 { 77 if (null == m_Event[eventID]) 78 { 79 m_Event[eventID] = new List<ClientEventDelagate>(); 80 } 81 m_Event[eventID].Add(func); 82 } 83 84 public void AddEvent(EventNode eventNode) 85 { 86 m_EventQueue.Enqueue(eventNode); 87 } 88 89 public void Proccess() 90 { 91 if (0 != m_EventQueue.Count) 92 { 93 EventNode mCur = m_EventQueue.Dequeue(); 94 if (null == m_Event[mCur.m_EventID]) 95 { 96 MonoBehaviour.print("event ID: " + mCur.m_EventID + " is null"); 97 } 98 else 99 { 100 List<ClientEventDelagate> curEventDelagate = m_Event[mCur.m_EventID]; 101 for (int i = 0; i < curEventDelagate.Count; ++i) 102 { 103 curEventDelagate[i](mCur.msg); 104 } 105 } 106 } 107 } 108 }EventDispath.cs
LanSocketBase.cs 沒什麼實際意義,主要就是定義一些大家都會使用到的變數等
1 using System.Threading; 2 using UnityEngine; 3 4 /* 5 *輕量級區域網伺服器。 6 * 協議如下 7 * 消息頭前2位元組保存當前消息長度 8 * 後面跟4位元組表示消息ID 9 * 再後面是消息實質內容 10 */ 11 12 namespace LanSocket 13 { 14 public class LanSocketBase 15 { 16 public static int m_MaxOnePackBuff = 1024 * 3; 17 public static int m_MaxAllBuff = 1024 * 50; 18 public static int m_HeadSize = 6; 19 protected bool m_HasInit = false; 20 protected byte[] m_OnePack; 21 protected int m_OnePackIndex; 22 private Mutex m_Mutex; 23 24 public void BaseInit() 25 { 26 m_HasInit = true; 27 m_Mutex = new Mutex(); 28 m_OnePack = new byte[m_MaxOnePackBuff+1]; 29 m_OnePackIndex = 0; 30 } 31 32 public void BaseRelease() 33 { 34 m_Mutex.Close(); 35 } 36 37 protected void Lock() 38 { 39 m_Mutex.WaitOne(); 40 //MonoBehaviour.print("Lock:" + Thread.CurrentThread.ManagedThreadId.ToString()); 41 } 42 43 protected void UnLock() 44 { 45 m_Mutex.ReleaseMutex(); 46 //MonoBehaviour.print("Unlock:" + Thread.CurrentThread.ManagedThreadId.ToString()); 47 } 48 } 49 }LanSocketBase.cs
MsgPack.cs 打包類,參數類型不夠自行擴展
1 using UnityEngine; 2 /* 3 * 通信協議 4 * 消息頭前2位元組保存當前消息長度 5 * 後面跟4位元組表示消息ID 6 * 再後面是消息實質內容 7 */ 8 9 namespace LanSocket 10 { 11 public class MsgPack : PackBase 12 { 13 public MsgPack() 14 { 15 m_OnePackIndex = LanSocketBase.m_HeadSize; 16 } 17 18 public void SetHead(int ID) 19 { 20 byte[] mBuff = System.BitConverter.GetBytes(ID); 21 System.Buffer.BlockCopy(mBuff, 0, m_OnePack, 2, 4); 22 } 23 24 public void PackEnd() 25 { 26 byte[] mBuff = System.BitConverter.GetBytes(m_OnePackIndex); 27 System.Buffer.BlockCopy(mBuff, 0, m_OnePack, 0, 2); 28 } 29 30 public void Packbool(bool data) 31 { 32 ushort curDatalen = 1; 33 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 34 { 35 MonoBehaviour.print("Packbool() longer lager than Max buff len"); 36 return; 37 } 38 byte[] mBuff = System.BitConverter.GetBytes(data); 39 Pack(mBuff, curDatalen); 40 } 41 42 public void Pack16bit(short data) 43 { 44 ushort curDatalen = 2; 45 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 46 { 47 MonoBehaviour.print("Pack16bit(short) longer lager than Max buff len"); 48 return; 49 } 50 byte[] mBuff = System.BitConverter.GetBytes(data); 51 Pack(mBuff, curDatalen); 52 } 53 public void Pack16bit(ushort data) 54 { 55 ushort curDatalen = 2; 56 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 57 { 58 MonoBehaviour.print("Pack16bit(ushort) longer lager than Max buff len"); 59 return; 60 } 61 byte[] mBuff = System.BitConverter.GetBytes(data); 62 Pack(mBuff, curDatalen); 63 } 64 public void Pack32bit(int data) 65 { 66 ushort curDatalen = 4; 67 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 68 { 69 MonoBehaviour.print("Pack32bit(int) longer lager than Max buff len"); 70 return; 71 } 72 byte[] mBuff = System.BitConverter.GetBytes(data); 73 Pack(mBuff, curDatalen); 74 } 75 public void Pack32bit(uint data) 76 { 77 ushort curDatalen = 4; 78 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 79 { 80 MonoBehaviour.print("Pack32bit(uint) longer lager than Max buff len"); 81 return; 82 } 83 byte[] mBuff = System.BitConverter.GetBytes(data); 84 Pack(mBuff, curDatalen); 85 } 86 public void Pack32bit(float data) 87 { 88 ushort curDatalen = 4; 89 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 90 { 91 MonoBehaviour.print("Pack32bit(float) longer lager than Max buff len"); 92 return; 93 } 94 byte[] mBuff = System.BitConverter.GetBytes(data); 95 Pack(mBuff, curDatalen); 96 } 97 public void Pack64bit(double data) 98 { 99 ushort curDatalen = 8; 100 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 101 { 102 MonoBehaviour.print("Pack64bit(double) longer lager than Max buff len"); 103 return; 104 } 105 byte[] mBuff = System.BitConverter.GetBytes(data); 106 Pack(mBuff, curDatalen); 107 } 108 public void Pack64bit(long data) 109 { 110 ushort curDatalen = 8; 111 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 112 { 113 MonoBehaviour.print("Pack64bit(long) longer lager than Max buff len"); 114 return; 115 } 116 byte[] mBuff = System.BitConverter.GetBytes(data); 117 Pack(mBuff, curDatalen); 118 } 119 120 public void PackString(string data, ushort len) 121 { 122 ushort curDatalen = len; 123 if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff) 124 { 125 MonoBehaviour.print("PackString() longer lager than Max buff len"); 126 return; 127 } 128 byte[] mBuff = System.Text.Encoding.UTF8.GetBytes(data); 129 Pack(mBuff, curDatalen); 130 } 131 132 void Pack(byte[] data, ushort len) 133 { 134 System.Buffer.BlockCopy(data, 0, m_OnePack, m_OnePackIndex, len); 135 m_OnePackIndex += len; 136 } 137 138 public byte[] GetByte() 139 { 140 return m_OnePack; 141 } 142 143 public int GetByteLen() 144 { 145 return m_OnePackIndex; 146 } 147 } 148 }MsgPack.cs
MsgUnPack.cs 解包類,返回類型不夠自己擴展
1 using UnityEngine; 2 /* 3 * 通信協議 4 * 消息頭前2位元組保存當前消息長度 5 * 後面跟4位元組表示消息ID 6 * 再後面是消息實質內容 7 */ 8 9 namespace LanSocket 10 { 11 class MsgUnPack : PackBase 12 { 13 ushort m_PackLen; 14 int m_MsgID; 15 public MsgUnPack() 16 { 17 } 18 19 void GetHead() 20 { 21 m_PackLen = System.BitConverter.ToUInt16(m_OnePack, 0); 22 m_MsgID = System.BitConverter.ToUInt16(m_OnePack, 2); 23 m_OnePackIndex = 6; 24 } 25 26 public MsgUnPack(byte[] mBuff, ushort len) 27 { 28 UnPack(mBuff, len); 29 } 30 31 public MsgUnPack(byte[] mBuff, ushort offset, ushort len) 32 { 33 UnPack(mBuff, offset, len); 34 } 35 36 public void UnPack(byte[] mBuff, ushort len) 37 { 38 System.Buffer.BlockCopy(mBuff, 0, m_OnePack, 0, len); 39 GetHead(); 40 } 41 42 public void UnPack(byte[] mBuff, ushort offset, ushort len) 43 { 44 System.Buffer.BlockCopy(mBuff, offset, m_OnePack, 0, len); 45 GetHead(); 46 } 47 48 public bool Readbool() 49 { 50 if (m_OnePackIndex + 1 > m_PackLen) 51 { 52 MonoBehaviour.print("Readbool() longer lager than Max buff len"); 53 return false; 54 } 55 bool data = System.BitConverter.ToBoolean(m_OnePack, m_OnePackIndex); 56 ++m_OnePackIndex; 57 return data; 58 } 59 60 public short ReadShort() 61 { 62 if (m_OnePackIndex + 2 > m_PackLen) 63 { 64 MonoBehaviour.print("ReadShort() longer lager than Max buff len"); 65 return 0; 66 } 67 short data = System.BitConverter.ToInt16(m_OnePack, m_OnePackIndex); 68 m_OnePackIndex += 2; 69 return data; 70 } 71 72 public ushort ReadUShort() 73 { 74 if (m_OnePackIndex + 2 > m_PackLen) 75 { 76 MonoBehaviour.print("ReadUShortbit() longer lager than Max buff len"); 77 return 0; 78 } 79 ushort data = System.BitConverter.ToUInt16(m_OnePack, m_OnePackIndex); 80 m_OnePackIndex += 2; 81 return data; 82 } 83 84 public int ReadInt() 85 { 86 if (m_OnePackIndex + 4 > m_PackLen) 87 { 88 MonoBehaviour.print("ReadInt() longer lager than Max buff len"); 89 return 0; 90 } 91 int data = System.BitConverter.ToInt32(m_OnePack, m_OnePackIndex); 92 m_OnePackIndex += 4; 93 return data; 94 } 95 96 public uint ReadUInt() 97 { 98 if (m_OnePackIndex + 4 > m_PackLen) 99 { 100 MonoBehaviour.print("ReadUInt() longer lager than Max buff len"); 101 return 0; 102 } 103 uint data = System.BitConverter.ToUInt32(m_OnePack, m_OnePackIndex); 104 m_OnePackIndex += 4; 105 return data; 106 } 107 108 public float ReadFloat() 109 { 110 if (m_OnePackIndex + 4 > m_PackLen) 111 { 112 MonoBehaviour.print("ReadFloat() longer lager than Max buff len"); 113 return 0.0f; 114 }