你的位置:首页 > 操作系统

[操作系统]u3d局域网游戏网络(c# socket select 模型)


之前写了一篇。

发完之后第二天实际应用到游戏之后还是发现了一些小毛病。

比如网络模块有重复使用(多对象)的情况。所以将静态类该成了普通类。

比如安卓下会有些异常出现导致游戏逻辑不正常。所以网络相关的函数有些加了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 LanSocket10 {11   class ClientMsgUnPack : MsgUnPack12   {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 LanSocket13 {14   public class LanSocketBase15   {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       }115       float data = System.BitConverter.ToSingle(m_OnePack, m_OnePackIndex);116       m_OnePackIndex += 4;117       return data;118     }119 120     public double ReadDouble()121     {122       if (m_OnePackIndex + 8 > m_PackLen)123       {124         MonoBehaviour.print("ReadDouble() longer lager than Max buff len");125         return 0.0f;126       }127       double data = System.BitConverter.ToDouble(m_OnePack, m_OnePackIndex);128       m_OnePackIndex += 8;129       return data;130     }131 132     public long ReadLong()133     {134       if (m_OnePackIndex + 8 > m_PackLen)135       {136         MonoBehaviour.print("ReadLong() longer lager than Max buff len");137         return 0;138       }139       long data = System.BitConverter.ToInt64(m_OnePack, m_OnePackIndex);140       m_OnePackIndex += 8;141       return data;142     }143 144     public ulong ReadULong()145     {146       if (m_OnePackIndex + 8 > m_PackLen)147       {148         MonoBehaviour.print("ReadULong() longer lager than Max buff len");149         return 0;150       }151       ulong data = System.BitConverter.ToUInt64(m_OnePack, m_OnePackIndex);152       m_OnePackIndex += 8;153       return data;154     }155 156     public string ReadString(ushort len)157     {158       if (m_OnePackIndex + len > m_PackLen)159       {160         MonoBehaviour.print("ReadString() longer lager than Max buff len");161         return "";162       }163       string data = System.Text.Encoding.UTF8.GetString(m_OnePack, m_OnePackIndex, len);164       m_OnePackIndex += len;165       return data;166     }167 168     public int GetMsgID()169     {170       return m_MsgID;171     }172   }173 }

MsgUnPack.cs

PackBase.cs 没什么实际意义,主要就是打包和解包类都会使用到的一些数据

 1 using System.Threading; 2  3 /* 4  *轻量级局域网服务器。  5  * 协议如下 6  * 消息头前2字节保存当前消息长度 7  * 后面跟4字节表示消息ID 8  * 再后面是消息实质内容 9 */10 11 namespace LanSocket12 {13   public class PackBase14   {15     protected int m_MaxOnePackBuff;16     protected byte[] m_OnePack;17     protected int m_OnePackIndex;18 19     public PackBase()20     {21       m_MaxOnePackBuff = LanSocketBase.m_MaxOnePackBuff;22       m_OnePack = new byte[m_MaxOnePackBuff];23       m_OnePackIndex = 0;24     }25   }26 }

PackBase.cs

SocketBase.cs 同上

 1 using System.Net.Sockets; 2 using System.Threading; 3 using System.Net; 4  5 public class SocketBase 6 { 7   protected bool m_HasInit = false; 8   protected Socket m_Socket; 9   protected Thread m_LinstenThread;10   protected IPEndPoint m_IP;11   protected Mutex m_Mutex;12 }

SocketBase.cs

 

新增的广播类(broadcast)

特别说下,udp没有握手,所以socket对象在shutdown的时候会出异常,具体知识我也不知道,我是试出来的,有知道的还望不吝赐教。

ReciveBroadcast.cs 广播接收器。服务器段需要长期保持打开,因为只要有新用户加入,服务器就需要下发数据。而客户端不需要,因为客户端一但连上,就不需要广播系统了。所以服务器长期保留,客户端用完销毁

 1 using UnityEngine; 2 using System.Net.Sockets; 3 using System.Net; 4 using System.Threading; 5 using System.Collections.Generic; 6  7 class ReciveBroadcast : SocketBase 8 { 9   public Queue<string> m_ServerIP;10   public void Start(int port)11   {12     if (m_HasInit)13     {14       return;15     }16     try17     {18       m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);19       m_IP = new IPEndPoint(IPAddress.Any, port);20       m_Socket.Bind(m_IP);21       MonoBehaviour.print("广播网络启动监听" + m_Socket.LocalEndPoint.ToString());22       m_LinstenThread = new Thread(ListenClientConnect);23       m_LinstenThread.Start();24       m_ServerIP = new Queue<string>();25       m_Mutex = new Mutex();26       m_HasInit = true;27     }28     catch (System.Exception ex)29     {30       MonoBehaviour.print("Broadcast reciver Start catch:" + ex.Message);31     }32   }33 34   void ListenClientConnect()35   {36     EndPoint ep = (EndPoint)m_IP;37     try38     {39       while (true)40       {41         Thread.Sleep(1);42         byte[] data = new byte[64];43         int recv = m_Socket.ReceiveFrom(data, ref ep);44         string stringData = System.Text.Encoding.UTF8.GetString(data, 0, recv);45         m_Mutex.WaitOne();46         m_ServerIP.Enqueue(stringData);47         m_Mutex.ReleaseMutex();48         MonoBehaviour.print("received: " + stringData + " from: " + ep.ToString());49       }50     }51     catch (System.Exception ex)52     {53       MonoBehaviour.print("Broadcast reciver ListenClientConnect out:" + ex.Message);54     }55   }56 57   public void Destroy()58   {59     if (!m_HasInit)60     {61       return;62     }63     m_Socket.Close();64     m_LinstenThread.Abort();65   }66 67   public string GetIP()68   {69     if (!m_HasInit)70     {71       return "";72     }73 74     try75     {76       m_Mutex.WaitOne();77       if (0 != m_ServerIP.Count)78       {79         m_Mutex.ReleaseMutex();80         return m_ServerIP.Dequeue();81       }82       m_Mutex.ReleaseMutex();83     }84     catch (System.Exception ex)85     {86       MonoBehaviour.print("Broadcast GetIP catch:" + ex.Message);87       return "";88     }89     return "";90   }91 }

ReciveBroadcast.cs

SendBroadcast.cs 广播发射器。同上

 1 using UnityEngine; 2 using System.Net.Sockets; 3 using System.Net; 4  5 class SendBroadcast : SocketBase 6 { 7   byte[] m_MyIP; 8   public void Start(int port) 9   {10     if (m_HasInit)11     {12       return;13     }14     try15     {16       m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);17       m_IP = new IPEndPoint(IPAddress.Broadcast, port);//255.255.255.25518       //m_IP = new IPEndPoint(IPAddress.Parse("192.168.255.255"), 9050);19 20       string mLocalIP = "";21       string hostname = Dns.GetHostName();22       IPHostEntry localHost = Dns.GetHostEntry(hostname);23       for (int i = 0; i < localHost.AddressList.Length; ++i)24       {25         if (localHost.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)26         {27           //MonoBehaviour.print(localHost.AddressList[i].ToString());28           mLocalIP = localHost.AddressList[i].ToString();29           break;30         }31       }32 33       if ("".Equals(m_MyIP))34       {35         MonoBehaviour.print("网络检测异常。请检查网络设置或接入网络");36         m_Socket.Close();37         m_Socket = null;38         return;39       }40       m_MyIP = System.Text.Encoding.UTF8.GetBytes(mLocalIP);41       m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);42       m_HasInit = true;43     }44     catch (System.Exception ex)45     {46       MonoBehaviour.print("Broadcast sender Start catch:" + ex.Message);47     }48   }49 50   public void Send()51   {52     if(null != m_Socket)53     {54       MonoBehaviour.print("send a broadcast");55       m_Socket.SendTo(m_MyIP, m_IP);56     }57   }58 59   public void Destroy()60   {61     if (!m_HasInit)62     {63       return;64     }65     m_Socket.Close();66   }67 }

SendBroadcast.cs

 

说明:网络模块也是根据网络上的代码加以修正和自己的经验修改完成。对于c# socket函数不熟,如果有什么地方可以优化或者用错或者传错参数,请指出赐教。

客户端网络(client)

SocketClient.cs 客户端网络模块。包含连接服务器、接受范围、处理返回数据等。

 1 using System.Net.Sockets; 2 using System.Net; 3 using System.Threading; 4 using UnityEngine; 5 using System.Collections.Generic; 6  7 /* 8  *轻量级局域网服务器。  9  * 协议如下 10  * 消息头前2字节保存当前消息长度 11  * 后面跟4字节表示消息ID 12  * 再后面是消息实质内容 13 */ 14  15 namespace LanSocket 16 { 17   class Client : LanSocketBase 18   { 19     Thread m_ReciveThread; 20     Socket m_Connect; 21     byte[] m_AllData; 22     int m_AllDataHead; 23     int m_AllDataEnd; 24     int m_MsgNum; 25  26     public void Start(string strIP, int port) 27     { 28       if (m_HasInit) 29       { 30         return; 31       } 32       //设定服务器IP地址  33       IPAddress ip = IPAddress.Parse(strIP); 34       Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 35       try 36       { 37         temp.Connect(new IPEndPoint(ip, port)); //配置服务器IP与端口  38         MonoBehaviour.print("连接服务器成功"); 39  40         BaseInit(); 41         m_Connect = temp; 42         m_ReciveThread = new Thread(ReceiveMessage); 43         m_ReciveThread.Start(); 44         m_AllData = new byte[LanSocketBase.m_MaxAllBuff + 1]; 45         m_AllDataHead = 0; 46         m_AllDataEnd = 0; 47         m_MsgNum = 0; 48       } 49       catch (System.Exception ex) 50       { 51         MonoBehaviour.print("连接服务器失败: " + ex.Message); 52         return; 53       } 54     } 55  56     private void PutDataToBuff(byte[] mClientSendBuff, int mReceiveNumber) 57     { 58       if (m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff) 59       { 60         byte[] mCurAllData = new byte[m_AllDataEnd - m_AllDataHead]; 61         System.Buffer.BlockCopy(m_AllData, m_AllDataHead, mCurAllData, 0, m_AllDataEnd - m_AllDataHead); 62         System.Buffer.BlockCopy(mCurAllData, 0, m_AllData, 0, m_AllDataEnd - m_AllDataHead); 63         m_AllDataEnd -= m_AllDataHead; 64         m_AllDataHead = 0; 65       } 66       int mOnePackStartPos = 0; 67       while (mReceiveNumber > 0) 68       { 69         if (0 == m_OnePackIndex) 70         { 71           ushort datalen = System.BitConverter.ToUInt16(mClientSendBuff, mOnePackStartPos); 72           if (datalen <= mReceiveNumber) 73           { 74             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_AllData, m_AllDataEnd, datalen); 75             m_AllDataEnd += datalen; 76  77             mOnePackStartPos += datalen; 78  79             mReceiveNumber -= datalen; 80             ++m_MsgNum; 81           } 82           else 83           { 84             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber); 85             m_OnePackIndex += mReceiveNumber; 86             mOnePackStartPos += mReceiveNumber; 87  88             mReceiveNumber -= mReceiveNumber; 89           } 90         } 91         else 92         { 93           ushort datalen = System.BitConverter.ToUInt16(m_OnePack, 0); 94           if (m_OnePackIndex + mReceiveNumber >= datalen) 95           { 96             int mNeedNum = datalen - m_OnePackIndex; 97             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mNeedNum); 98             mOnePackStartPos += mNeedNum; 99             100             System.Buffer.BlockCopy(m_OnePack, 0, m_AllData, m_AllDataEnd, datalen);101             m_OnePackIndex = 0;102 103             mReceiveNumber -= mNeedNum;104           }105           else106           {107             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);108             m_OnePackIndex += mReceiveNumber;109             mOnePackStartPos += mReceiveNumber;110 111             mReceiveNumber -= mReceiveNumber;112           }113         }114       }115     }116 117     public void Destroy()118     {119       if (!m_HasInit)120       {121         return;122       }123       BaseRelease();124       ShutDownConnect();125       m_MsgNum = 0;126     }127 128     public void GetMsg(ref MsgUnPack msg)129     {130       if (!m_HasInit)131       {132         return;133       }134       try135       {136         Lock();137         if (0 != m_MsgNum)138         {139           ushort datalen = System.BitConverter.ToUInt16(m_AllData, m_AllDataHead);140           msg = new MsgUnPack(m_AllData, (ushort)m_AllDataHead, (ushort)datalen);141           m_AllDataHead += datalen;142           --m_MsgNum;143         }144       }145       finally146       {147         UnLock();148       }149     }150 151     /// <summary> 152     /// 接收消息 153     /// </summary> 154     public void ReceiveMessage()155     {156       while (true)157       {158         Thread.Sleep(1);159         try160         {161           //通过clientSocket接收数据 162           byte[] mClientSendBuff = new byte[m_MaxOnePackBuff + 1];163           int mReceiveNumber = m_Connect.Receive(mClientSendBuff);164           if (0 == mReceiveNumber)165           {166             MonoBehaviour.print("disconnect");167             ShutDownConnect();168           }169           else if (mReceiveNumber > 0)170           {171             try172             {173               Lock();174               PutDataToBuff(mClientSendBuff, mReceiveNumber);175             }176             catch (System.Exception ex)177             {178               MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);179             }180             finally181             {182               UnLock();183             }184           }185           else186           {187             MonoBehaviour.print("one connect recive a error num: " + mReceiveNumber.ToString());188           }189         }190         catch (System.Exception ex)191         {192           MonoBehaviour.print("ReceiveMessage catch: " + ex.Message);193           ShutDownConnect();194         }195       }196     }197 198     public void Send(ref MsgPack msg)199     {200       try201       {202         Lock();203         m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);204       }205       finally206       {207         UnLock();208       }209     }210 211     public void ShutDownConnect()212     {213       m_ReciveThread.Abort();214       if (m_Connect.Connected)215       {216         m_Connect.Shutdown(SocketShutdown.Both);217       }218       m_Connect.Close();219     }220   }221 }

SocketClient.cs

服务器网络(server)

SocketServer.cs 服务器网络模块。同上,额外有玩家池。

 1 using System.Net.Sockets; 2 using System.Net; 3 using System.Threading; 4 using UnityEngine; 5 using System.Collections.Generic; 6 /* 7  *轻量级局域网服务器。  8  * 协议如下 9  * 消息头前2字节保存当前消息长度 10  * 后面跟4字节表示消息ID 11  * 再后面是消息实质内容 12 */ 13  14 namespace LanSocket 15 { 16   class ClientConnect 17   { 18     public byte[] m_AllData; 19     public int m_AllDataHead; 20     public int m_AllDataEnd; 21     public int m_MsgCount; 22     public byte[] m_OnePack; 23     public int m_OnePackIndex; 24     public Socket m_Connect; 25     public long m_UserID; 26  27     public ClientConnect() 28     { 29       m_AllData = new byte[LanSocketBase.m_MaxAllBuff]; 30       m_AllDataHead = 0; 31       m_AllDataEnd = 0; 32       m_MsgCount = 0; 33       m_OnePack = new byte[LanSocketBase.m_MaxOnePackBuff]; 34       m_OnePackIndex = 0; 35       m_Connect = null; 36       m_UserID = 0; 37     } 38  39     public void Reset() 40     { 41       m_AllDataHead = 0; 42       m_AllDataEnd = 0; 43       m_MsgCount = 0; 44       m_OnePackIndex = 0; 45       m_Connect = null; 46       m_UserID = 0; 47     } 48   } 49   class Server : LanSocketBase 50   { 51     Queue<int> m_MsgOrder; 52  53     Socket m_ServerSocket; 54     Thread m_LinstenThread; 55     Thread m_ReciveThread; 56     System.Collections.ArrayList m_ServerSocketList; 57     System.Collections.ArrayList m_listenSocketList; 58     System.Collections.ArrayList m_DeleteSocketList; 59     int m_MaxClientConnect = 10; 60     ClientConnect[] m_ConnectPool; 61     Queue<int> m_EmptyConnect; 62     public void Start(int port) 63     { 64       if (m_HasInit) 65       { 66         return; 67       } 68       string mLocalIP = ""; 69  70       string mHostName = Dns.GetHostName(); 71       IPHostEntry localHost = Dns.GetHostEntry(mHostName); 72       for (int i = 0; i < localHost.AddressList.Length; ++i) 73       { 74         if (localHost.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 75         { 76           //MonoBehaviour.print(localHost.AddressList[i].ToString()); 77           mLocalIP = localHost.AddressList[i].ToString(); 78           break; 79         } 80       } 81  82       if ("".Equals(mLocalIP)) 83       { 84         MonoBehaviour.print("网络检测异常。请检查网络设置或接入网络"); 85         return; 86       } 87       BaseInit(); 88       m_MsgOrder = new Queue<int>(); 89  90       //服务器IP地址  91       IPAddress ip = IPAddress.Parse(mLocalIP); 92       m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 93       m_ServerSocket.Bind(new IPEndPoint(ip, port)); //绑定IP地址:端口  94       m_ServerSocket.Listen(10);  //设定最多10个排队连接请求  95       MonoBehaviour.print("游戏网络启动监听" + m_ServerSocket.LocalEndPoint.ToString()); 96  97       m_ServerSocketList = new System.Collections.ArrayList(); 98       m_listenSocketList = new System.Collections.ArrayList(); 99       m_DeleteSocketList = new System.Collections.ArrayList();100 101       m_ConnectPool = new ClientConnect[m_MaxClientConnect];102       m_EmptyConnect = new Queue<int>();103       for (int i = 0; i < m_MaxClientConnect; ++i)104       {105         m_ConnectPool[i] = new ClientConnect();106         m_EmptyConnect.Enqueue(i);107       }108       //通过Clientsoket发送数据 109       m_ReciveThread = new Thread(ReceiveMessage);110       m_ReciveThread.Start();111       m_LinstenThread = new Thread(ListenClientConnect);112       m_LinstenThread.Start();113     }114 115     /// <summary> 116     /// 监听客户端连接 117     /// </summary> 118     public void ListenClientConnect()119     {120       while (true)121       {122         Thread.Sleep(500);123         m_ServerSocketList.Add(m_ServerSocket);124         Socket.Select(m_ServerSocketList, null, null, 1000);125         for (int i = 0; i < m_ServerSocketList.Count; ++i)126         {127           Socket clientSocket = ((Socket)m_ServerSocketList[i]).Accept();128           if (null != clientSocket)129           {130             try131             {132               Lock();133               if (0 == m_EmptyConnect.Count)134               {135                 MonoBehaviour.print("链接已经达到最大上线,丢弃当前连接");136                 clientSocket.Shutdown(SocketShutdown.Both);137                 clientSocket.Close();138               }139               else140               {141                 //m_listenSocketList.Add(clientSocket);142                 int mSlot = m_EmptyConnect.Dequeue();143                 m_ConnectPool[mSlot].m_Connect = clientSocket;144                 m_ConnectPool[mSlot].m_UserID = System.DateTime.Now.ToFileTime();145                 MonoBehaviour.print("成功连接一个客户端,编号:" + mSlot.ToString());146               }147             }148             finally149             {150               UnLock();151             }152           }153         }154         m_ServerSocketList.Clear();155       }156     }157 158     private bool PutDataToBuff(byte[] mClientSendBuff, int mReceiveNumber, Socket client)159     {160       ClientConnect curPlayer = null;161       int mSlot = -1;162       for (int i = 0; i < m_MaxClientConnect; ++i)163       {164         if (client == m_ConnectPool[i].m_Connect)165         {166           curPlayer = m_ConnectPool[i];167           mSlot = i;168           break;169         }170       }171       if (null == curPlayer)172       {173         return false;174       }175       if (curPlayer.m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff)176       {177         byte[] mCurAllData = new byte[curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead];178         System.Buffer.BlockCopy(curPlayer.m_AllData, curPlayer.m_AllDataHead, mCurAllData, 0, curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead);179         System.Buffer.BlockCopy(mCurAllData, 0, curPlayer.m_AllData, 0, curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead);180         curPlayer.m_AllDataEnd -= curPlayer.m_AllDataHead;181         curPlayer.m_AllDataHead = 0;182       }183       int mOnePackStartPos = 0;184       while (mReceiveNumber > 0)185       {186         if (0 == m_OnePackIndex)187         {188           ushort datalen = System.BitConverter.ToUInt16(mClientSendBuff, mOnePackStartPos);189           if (datalen > LanSocketBase.m_MaxOnePackBuff || datalen < LanSocketBase.m_HeadSize)190           {191             return false;192           }193           if (datalen <= mReceiveNumber)194           {195             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_AllData, curPlayer.m_AllDataEnd, datalen);196             curPlayer.m_AllDataEnd += datalen;197             mOnePackStartPos += datalen;198 199             mReceiveNumber -= datalen;200 201             m_MsgOrder.Enqueue(mSlot);202           }203           else204           {205             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);206             m_OnePackIndex += mReceiveNumber;207             mOnePackStartPos += mReceiveNumber;208 209             mReceiveNumber -= mReceiveNumber;210           }211         }212         else213         {214           ushort datalen = System.BitConverter.ToUInt16(m_OnePack, 0);215           if (datalen > LanSocketBase.m_MaxOnePackBuff || datalen < LanSocketBase.m_HeadSize)216           {217             return false;218           }219           if (m_OnePackIndex + mReceiveNumber >= datalen)220           {221             int mNeedNum = datalen - m_OnePackIndex;222             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mNeedNum);223             mOnePackStartPos += mNeedNum;224 225             System.Buffer.BlockCopy(m_OnePack, 0, curPlayer.m_AllData, curPlayer.m_AllDataEnd, datalen);226             m_OnePackIndex = 0;227 228             mReceiveNumber -= mNeedNum;229 230             m_MsgOrder.Enqueue(mSlot);231           }232           else233           {234             System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);235             m_OnePackIndex += mReceiveNumber;236             mOnePackStartPos += mReceiveNumber;237 238             mReceiveNumber -= mReceiveNumber;239           }240         }241       }242 243       return true;244     }245 246     /// <summary> 247     /// 接收消息 248     /// </summary> 249     public void ReceiveMessage()250     {251       try252       {253         while (true)254         {255           Thread.Sleep(1);256           for (int i = 0; i < m_MaxClientConnect; ++i)257           {258             if (null != m_ConnectPool[i].m_Connect)259             {260               m_listenSocketList.Add(m_ConnectPool[i].m_Connect);261             }262           }263           if (0 == m_listenSocketList.Count)264           {265             continue;266           }267           Socket.Select(m_listenSocketList, null, null, 1000);268           for (int i = 0; i < m_listenSocketList.Count; ++i)269           {270             Socket mClient = (Socket)m_listenSocketList[i];271             //try272             //{273             //通过clientSocket接收数据 274             byte[] mClientSendBuff = new byte[m_MaxOnePackBuff];275             int mReceiveNumber = mClient.Receive(mClientSendBuff);276             if (0 == mReceiveNumber)277             {278               m_DeleteSocketList.Add(mClient);279             }280             else if (mReceiveNumber > 0)281             {282               try283               {284                 Lock();285                 bool rt = PutDataToBuff(mClientSendBuff, mReceiveNumber, mClient);286                 if (!rt)287                 {288                   m_DeleteSocketList.Add(mClient);289                 }290               }291               catch (System.Exception ex)292               {293                 MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);294               }295               finally296               {297                 UnLock();298               }299             }300             else301             {302               MonoBehaviour.print("one connect recive a error num: " + mReceiveNumber.ToString());303             }304             //}305             //catch (System.Exception ex)306             //{307             //  MonoBehaviour.print("ReceiveMessage catch: " + ex.Message);308             //  m_DeleteSocketList.Add(mClient);309             //}310           }311           m_listenSocketList.Clear();312           if (0 != m_DeleteSocketList.Count)313           {314             ShutDownConnect();315           }316         }317 318       }319       catch (System.Exception ex)320       {321         MonoBehaviour.print("ReceiveMessage out:" + ex.Message);322       }323 324     }325 326     /// <summary> 327     /// 程序退出销毁 328     /// </summary> 329     public void Destroy()330     {331       if (!m_HasInit)332       {333         return;334       }335       m_LinstenThread.Abort();336       m_ReciveThread.Abort();337       m_listenSocketList.Clear();338 339       for (int i = 0; i < m_ServerSocketList.Count; ++i)340       {341         Socket mServer = (Socket)m_ServerSocketList[i];342         if (mServer.Connected)343         {344           mServer.Shutdown(SocketShutdown.Both);345         }346         mServer.Close();347       }348       m_ServerSocketList.Clear();349 350       for (int i = 0; i < m_MaxClientConnect; ++i)351       {352         if (null != m_ConnectPool[i].m_Connect)353         {354           if (m_ConnectPool[i].m_Connect.Connected)355           {356             m_ConnectPool[i].m_Connect.Shutdown(SocketShutdown.Both);357           }358           m_ConnectPool[i].m_Connect.Close();359           m_ConnectPool[i].m_Connect = null;360         }361       }362       m_EmptyConnect.Clear();363       BaseRelease();364     }365 366     /// <summary> 367     /// 销毁一个连接 368     /// </summary> 369     void ShutDownConnect()370     {371       try372       {373         Lock();374         for (int j = 0; j < m_DeleteSocketList.Count; ++j)375         {376           Socket connect = (Socket)m_DeleteSocketList[j];377           for (int i = 0; i < m_MaxClientConnect; ++i)378           {379             if (connect == m_ConnectPool[i].m_Connect)380             {381               connect.Shutdown(SocketShutdown.Both);382               connect.Close();383               m_ConnectPool[i].Reset();384               m_EmptyConnect.Enqueue(i);385               MonoBehaviour.print("关闭一个连接,编号:" + i.ToString());386               break;387             }388           }389         }390       }391       catch (System.Exception ex)392       {393         MonoBehaviour.print("ShutDownConnect catch: " + ex.Message);394       }395       finally396       {397         m_DeleteSocketList.Clear();398         UnLock();399       }400     }401 402     /// <summary> 403     /// 获取一个数据 404     /// </summary> 405     public void GetMsg(ref ClientMsgUnPack msg)406     {407       if(!m_HasInit)408       {409         return;410       }411       try412       {413         Lock();414         if (0 != m_MsgOrder.Count)415         {416           int mSlot = m_MsgOrder.Dequeue();417           ClientConnect curPlayer = m_ConnectPool[mSlot];418           ushort mOnePackLen = System.BitConverter.ToUInt16(curPlayer.m_AllData, curPlayer.m_AllDataHead);419           msg = new ClientMsgUnPack(curPlayer.m_AllData, (ushort)curPlayer.m_AllDataHead, (ushort)mOnePackLen, mSlot);420           msg.SetUserID(curPlayer.m_UserID);421           curPlayer.m_AllDataHead += mOnePackLen;422         }423       }424       finally425       {426         UnLock();427       }428     }429 430     public void SendTo(ref MsgPack msg, long userID)431     {432       try433       {434         Lock();435         for(int i = 0 ; i < m_MaxClientConnect ; ++i)436         {437           ClientConnect curPlayer = m_ConnectPool[i];438           if (null != curPlayer.m_Connect && curPlayer.m_UserID == userID)439           {440             curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);441             break;442           }443         }444       }445       finally446       {447         UnLock();448       }449     }450 451     public void SendToAll(ref MsgPack msg)452     {453       try454       {455         Lock();456         for (int i = 0; i < m_MaxClientConnect; ++i)457         {458           ClientConnect curPlayer = m_ConnectPool[i];459           if (null != curPlayer.m_Connect)460           {461             curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);462             break;463           }464         }465       }466       finally467       {468         UnLock();469       }470     }471   }472 }

SocketServer.cs

 

外部配套模块

ClientMain.cs u3d下的一个启动客户端网络模块的控件

 1 using UnityEngine; 2 using System.Collections; 3  4 public class ClientMain : MonoBehaviour { 5  6   // Use this for initialization 7   ClientEventDispath m_Msg; 8   SendBroadcast m_Sender; 9   ReciveBroadcast m_Reciver; 10   LanSocket.Client m_GameNet; 11   string m_GameServerIP; 12   bool m_bReady; 13   float m_BroadTime; 14  15   void Start ()  16   { 17     m_Sender = new SendBroadcast(); 18     m_Sender.Start(6666); 19     m_Reciver = new ReciveBroadcast(); 20     m_Reciver.Start(6688); 21  22     m_GameNet = new LanSocket.Client(); 23  24     m_GameServerIP = ""; 25  26     m_bReady = false; 27     m_BroadTime = 0.0f; 28  29     EventDispathBase.g_MaxEventNum = (int)NetMsgID.NET_MSG_END; 30     m_Msg = new ClientEventDispath(); 31     m_Msg.RegistEvent((int)NetMsgID.S2C_SEND_ANIMAL_DATA, Action_S2C_SEND_ANIMAL_DATA); 32   } 33    34   // Update is called once per frame 35   void Update () 36   { 37     if (m_bReady) 38     { 39       LanSocket.MsgUnPack msg = null; 40       m_GameNet.GetMsg(ref msg); 41       if (null != msg) 42       { 43         print("here have one msg on client"); 44       } 45  46       if (Input.GetKeyUp(KeyCode.Space)) 47       { 48         LanSocket.MsgPack sendMsg = new LanSocket.MsgPack(); 49         sendMsg.SetHead((int)NetMsgID.C2S_SELECT_ANIMAL); 50         sendMsg.Pack16bit(1); 51         sendMsg.PackEnd(); 52         m_GameNet.Send(ref sendMsg); 53         print("send 1"); 54       } 55     } 56     else 57     { 58       m_GameServerIP = m_Reciver.GetIP(); 59       if ("".Equals(m_GameServerIP)) 60       { 61         m_BroadTime -= Time.deltaTime; 62         if(m_BroadTime - Time.deltaTime < 0.0f) 63         { 64           m_BroadTime = 5.0f; 65           m_Sender.Send(); 66         } 67       } 68       else 69       { 70         print("get broadcast ip:" + m_GameServerIP); 71         GameStart(); 72       } 73     } 74   } 75   void OnDestroy() 76   { 77     m_GameNet.Destroy(); 78     if(null != m_Reciver) 79     { 80       m_Reciver.Destroy(); 81     } 82     if (null != m_Sender) 83     { 84       m_Sender.Destroy(); 85     } 86   } 87  88   void GameStart() 89   { 90     m_bReady = true; 91     m_GameNet.Start(m_GameServerIP, 8888); 92     try 93     { 94       m_Reciver.Destroy(); 95       m_Sender.Destroy(); 96     } 97     catch (System.Exception ex) 98     { 99       MonoBehaviour.print("GameStart catch:" + ex.Message);100     }101     m_Reciver = null;102     m_Reciver = null;103   }104 105   void Action_S2C_SEND_ANIMAL_DATA(LanSocket.MsgUnPack msg)106   {107   }108 }

ClientMain.cs

Common.cs 定义的网络通信的消息ID

 1 using UnityEngine; 2 using System.Collections; 3  4 enum NetMsgID 5 { 6   NET_MSG_START = 100, 7   S2C_SEND_ANIMAL_DATA, 8   C2S_SELECT_ANIMAL, 9 10   NET_MSG_END,11 }

Common.cs

ServerMain.cs u3d下的一个启动服务器网络模块的控件

 1 using UnityEngine; 2 using System.Collections; 3  4 public class ServerMain : MonoBehaviour  5 { 6   bool m_Destroy; 7   ServerEventDispath m_ClientMsg; 8   ReciveBroadcast m_Reciver; 9   SendBroadcast m_Sender;10   LanSocket.Server m_GameNet;11   void Start () 12   {13     m_Destroy = false;14     //广播15     m_Reciver = new ReciveBroadcast();16     m_Reciver.Start(6666);17     m_Sender = new SendBroadcast();18     m_Sender.Start(6688);19 20     //游戏网络21     m_GameNet = new LanSocket.Server();22     m_GameNet.Start(8888);23 24     m_ClientMsg = new ServerEventDispath();25     m_ClientMsg.RegistEvent(123, Action_123);26   }27   28   // Update is called once per frame29   void Update () 30   {31     if(!m_Destroy)32     {33       LanSocket.ClientMsgUnPack clientMsg = null;34       m_GameNet.GetMsg(ref clientMsg);35       if (null != clientMsg)36       {37         print("Msg:" + clientMsg.GetMsgID() + " from: " + clientMsg.GetUserID());38 39         EventNode mNode = new EventNode();40         mNode.m_EventID = clientMsg.GetMsgID(); ;41         mNode.msg = clientMsg;42         m_ClientMsg.AddEvent(mNode);43       }44 45       if(!"".Equals(m_Reciver.GetIP()))46       {47         m_Sender.Send();48       }49 50       m_ClientMsg.Proccess();51     }52   }53 54   void OnDestroy()55   {56     m_Destroy = true;57     m_GameNet.Destroy();58     m_Reciver.Destroy();59     m_Sender.Destroy();60   }61 62   void Action_123(LanSocket.ClientMsgUnPack msg)63   {64     long userID = msg.GetUserID();65     ushort accountLen = msg.ReadUShort();66     string account = msg.ReadString(accountLen);67     ushort passLen = msg.ReadUShort();68     string pass = msg.ReadString(passLen);69 70     print("Action_123 account: " + account + " pass word: " + pass+" from user: " + userID);71 72     LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();73     sendMsg.SetHead(123);74     string strAccount = "test account";75     sendMsg.Pack16bit((ushort)strAccount.Length);76     sendMsg.PackString(strAccount, (ushort)strAccount.Length);77     string strPass = "test pass word";78     sendMsg.Pack16bit((ushort)strPass.Length);79     sendMsg.PackString(strPass, (ushort)strPass.Length);80     sendMsg.PackEnd();81     m_GameNet.SendTo(ref sendMsg, msg.GetUserID());82   }83 }

ServerMain.cs

 

伙计们,有代码分享出来。利人利己。

你问为什么会利己?

等你换了工作找不到原本的代码的时候你就知道传到网上是一件幸福的事。