• 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 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             }
    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 LanSocket
    12 {
    13     public class PackBase
    14     {
    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         try
    17         {
    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         try
    38         {
    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         try
    75         {
    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         try
    15         {
    16             m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    17             m_IP = new IPEndPoint(IPAddress.Broadcast, port);//255.255.255.255
    18             //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                     else
    106                     {
    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             try
    135             {
    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             finally
    146             {
    147                 UnLock();
    148             }
    149         }
    150 
    151         /// <summary>  
    152         /// 接收消息  
    153         /// </summary>  
    154         public void ReceiveMessage()
    155         {
    156             while (true)
    157             {
    158                 Thread.Sleep(1);
    159                 try
    160                 {
    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                         try
    172                         {
    173                             Lock();
    174                             PutDataToBuff(mClientSendBuff, mReceiveNumber);
    175                         }
    176                         catch (System.Exception ex)
    177                         {
    178                             MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);
    179                         }
    180                         finally
    181                         {
    182                             UnLock();
    183                         }
    184                     }
    185                     else
    186                     {
    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             try
    201             {
    202                 Lock();
    203                 m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
    204             }
    205             finally
    206             {
    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                         try
    131                         {
    132                             Lock();
    133                             if (0 == m_EmptyConnect.Count)
    134                             {
    135                                 MonoBehaviour.print("链接已经达到最大上线,丢弃当前连接");
    136                                 clientSocket.Shutdown(SocketShutdown.Both);
    137                                 clientSocket.Close();
    138                             }
    139                             else
    140                             {
    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                         finally
    149                         {
    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                     else
    204                     {
    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                 else
    213                 {
    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                     else
    233                     {
    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             try
    252             {
    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                         //try
    272                         //{
    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                             try
    283                             {
    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                             finally
    296                             {
    297                                 UnLock();
    298                             }
    299                         }
    300                         else
    301                         {
    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             try
    372             {
    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             finally
    396             {
    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             try
    412             {
    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             finally
    425             {
    426                 UnLock();
    427             }
    428         }
    429 
    430         public void SendTo(ref MsgPack msg, long userID)
    431         {
    432             try
    433             {
    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             finally
    446             {
    447                 UnLock();
    448             }
    449         }
    450 
    451         public void SendToAll(ref MsgPack msg)
    452         {
    453             try
    454             {
    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             finally
    467             {
    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 frame
    29     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

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

    你问为什么会利己?

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

  • 相关阅读:
    图的理论基础
    哈夫曼树(三)之 Java详解
    哈夫曼树(二)之 C++详解
    哈夫曼树(一)之 C语言详解
    基数排序
    桶排序
    归并排序
    堆排序
    选择排序
    希尔排序
  • 原文地址:https://www.cnblogs.com/saucerman/p/5555793.html
Copyright © 2020-2023  润新知