• c# socket select 模型代码(u3d)


    其实写过多次网络链接。但是因为换了工作,又没电脑在身边,所以以前的代码都没办法翻出来用。

    所以从今天起,一些常用的代码只好放到网上。

    公司有一个局域网的游戏。本来想用u3d的rpc就可以完成。但是后来说要传语音。于是只有写一个tcp。

    目前完成的模块大的说就两块,网络和消息分发。

    服务器有玩家池的管理。

    网络部分没有想得很详细。因为是局域网,所以也不存在多大开销。如果有需要上千的需求,可能还要优化下代码结构以及锁。

    有缘之人自取。

    无论你干什么,我都没任何要求。唯一的要求,如果你发现有bug,或者什么地方改改更好,请告诉我。谢谢!

    socket部分

      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         static Queue<int> m_MsgOrder;
     52 
     53         static Socket m_ServerSocket;
     54         static Thread m_LinstenThread;
     55         static Thread m_ReciveThread;
     56         static System.Collections.ArrayList m_ServerSocketList;
     57         static System.Collections.ArrayList m_listenSocketList;
     58         static System.Collections.ArrayList m_DeleteSocketList;
     59         static int m_MaxClientConnect = 10;
     60         static ClientConnect[] m_ConnectPool;
     61         static Queue<int> m_EmptyConnect;
     62         public static void Start()
     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             LanSocketBase.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, 8885));  //绑定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 static 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 static 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 static 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 static 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             LanSocketBase.BaseRelease();
    364         }
    365 
    366         /// <summary>  
    367         /// 销毁一个连接  
    368         /// </summary>  
    369         static 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 static void GetMsg(ref ClientMsgUnPack msg)
    406         {
    407             try
    408             {
    409                 Lock();
    410                 if (0 != m_MsgOrder.Count)
    411                 {
    412                     int mSlot = m_MsgOrder.Dequeue();
    413                     ClientConnect curPlayer = m_ConnectPool[mSlot];
    414                     ushort mOnePackLen = System.BitConverter.ToUInt16(curPlayer.m_AllData, curPlayer.m_AllDataHead);
    415                     msg = new ClientMsgUnPack(curPlayer.m_AllData, (ushort)curPlayer.m_AllDataHead, (ushort)mOnePackLen, mSlot);
    416                     msg.SetUserID(curPlayer.m_UserID);
    417                     curPlayer.m_AllDataHead += mOnePackLen;
    418                 }
    419             }
    420             finally
    421             {
    422                 UnLock();
    423             }
    424         }
    425 
    426         public static void SendTo(ref MsgPack msg, long userID)
    427         {
    428             try
    429             {
    430                 Lock();
    431                 for(int i = 0 ; i < m_MaxClientConnect ; ++i)
    432                 {
    433                     ClientConnect curPlayer = m_ConnectPool[i];
    434                     if (null != curPlayer.m_Connect && curPlayer.m_UserID == userID)
    435                     {
    436                         curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
    437                         break;
    438                     }
    439                 }
    440             }
    441             finally
    442             {
    443                 UnLock();
    444             }
    445         }
    446 
    447         public static void SendToAll(ref MsgPack msg)
    448         {
    449             try
    450             {
    451                 Lock();
    452                 for (int i = 0; i < m_MaxClientConnect; ++i)
    453                 {
    454                     ClientConnect curPlayer = m_ConnectPool[i];
    455                     if (null != curPlayer.m_Connect)
    456                     {
    457                         curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
    458                         break;
    459                     }
    460                 }
    461             }
    462             finally
    463             {
    464                 UnLock();
    465             }
    466         }
    467     }
    468 }
    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  * 协议如下
     10  * 消息头前2字节保存当前消息长度
     11  * 后面跟4字节表示消息ID
     12  * 再后面是消息实质内容
     13  */
     14 
     15 namespace LanSocket
     16 {
     17     class Client : LanSocketBase
     18     {
     19         static Thread m_ReciveThread;
     20         static Socket m_Connect;
     21         static byte[] m_AllData;
     22         static int m_AllDataHead;
     23         static int m_AllDataEnd;
     24         static int m_MsgNum;
     25 
     26         public static void Start()
     27         {
     28             if (m_HasInit)
     29             {
     30                 return;
     31             }
     32             //设定服务器IP地址  
     33             IPAddress ip = IPAddress.Parse("192.168.1.109");
     34             Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     35             try
     36             {
     37                 temp.Connect(new IPEndPoint(ip, 8885)); //配置服务器IP与端口  
     38                 MonoBehaviour.print("连接服务器成功");
     39 
     40                 LanSocketBase.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
     50             {
     51                 MonoBehaviour.print("连接服务器失败");
     52                 return;
     53             }
     54         }
     55 
     56         private static 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 static void Destroy()
    118         {
    119             if (!m_HasInit)
    120             {
    121                 return;
    122             }
    123             LanSocketBase.BaseRelease();
    124             ShutDownConnect();
    125             m_MsgNum = 0;
    126         }
    127 
    128         public static 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 static 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 static 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 static 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

    支持类部分

     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 static bool m_HasInit = false;
    20         protected static byte[] m_OnePack;
    21         protected static int m_OnePackIndex;
    22         private static Mutex m_Mutex;
    23 
    24         public static 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 static void BaseRelease()
    33         {
    34             m_Mutex.Close();
    35         }
    36 
    37         protected static void Lock()
    38         {
    39             m_Mutex.WaitOne();
    40             //MonoBehaviour.print("Lock:" + Thread.CurrentThread.ManagedThreadId.ToString());
    41         }
    42 
    43         protected static void UnLock()
    44         {
    45             m_Mutex.ReleaseMutex();
    46             //MonoBehaviour.print("Unlock:" + Thread.CurrentThread.ManagedThreadId.ToString());
    47         }
    48     }
    49 }
    LanSocketBase
     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
      1 using UnityEngine;
      2 /*
      3  * 通信协议
      4  * 消息头前2字节保存当前消息长度
      5  * 后面跟4字节表示消息ID
      6  * 再后面是消息实质内容
      7  */
      8 
      9 namespace LanSocket
     10 {
     11     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
      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
     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
     1 using UnityEngine;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 
     5 delegate void EventDelagate(LanSocket.ClientMsgUnPack msg);
     6 
     7 class EventNode
     8 {
     9     public int m_EventID;
    10     public LanSocket.ClientMsgUnPack msg;
    11 }
    12 
    13 class EventDispath
    14 {
    15     public static int g_MaxEventNum = 300;
    16     List<EventDelagate>[] m_Event;
    17     Queue<EventNode> m_EventQueue;
    18     public EventDispath()
    19     {
    20         m_Event = new List<EventDelagate>[g_MaxEventNum];
    21         m_EventQueue = new Queue<EventNode>();
    22     }
    23 
    24     public void RegistEvent(int eventID, EventDelagate func)
    25     {
    26         if(null == m_Event[eventID])
    27         {
    28             m_Event[eventID] = new List<EventDelagate>();
    29         }
    30         m_Event[eventID].Add(func);
    31     }
    32 
    33     public void AddEvent(EventNode eventNode)
    34     {
    35         m_EventQueue.Enqueue(eventNode);
    36     }
    37 
    38     public void Proccess()
    39     {
    40         if (0 != m_EventQueue.Count)
    41         {
    42             EventNode mCur = m_EventQueue.Dequeue();
    43             if (null == m_Event[mCur.m_EventID])
    44             {
    45                 MonoBehaviour.print("event ID: "+ mCur.m_EventID+" is null");
    46             }
    47             else
    48             {
    49                 List<EventDelagate> curEventDelagate = m_Event[mCur.m_EventID];
    50                 for(int i = 0 ; i < curEventDelagate.Count ; ++i)
    51                 {
    52                     curEventDelagate[i](mCur.msg);
    53                 }
    54             }
    55         }
    56     }
    57 }
    EventDispath.cs

    unity部分

     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class ServerMain : MonoBehaviour 
     5 {
     6     bool m_Destroy;
     7     EventDispath m_ClientMsg;
     8     void Start () 
     9     {
    10         m_Destroy = false;
    11         //服务器IP地址  
    12         LanSocket.Server.Start();
    13         m_ClientMsg = new EventDispath();
    14         m_ClientMsg.RegistEvent(123, Action_123);
    15 
    16     }
    17     
    18     // Update is called once per frame
    19     void Update () 
    20     {
    21         if(!m_Destroy)
    22         {
    23             LanSocket.ClientMsgUnPack clientMsg = null;
    24             LanSocket.Server.GetMsg(ref clientMsg);
    25             if (null != clientMsg)
    26             {
    27                 print("Msg:" + clientMsg.GetMsgID() + " from: " + clientMsg.GetUserID());
    28 
    29                 EventNode mNode = new EventNode();
    30                 mNode.m_EventID = clientMsg.GetMsgID(); ;
    31                 mNode.msg = clientMsg;
    32                 m_ClientMsg.AddEvent(mNode);
    33             }
    34 
    35             m_ClientMsg.Proccess();
    36         }
    37     }
    38 
    39     void OnDestroy()
    40     {
    41         m_Destroy = true;
    42         LanSocket.Server.Destroy();
    43     }
    44 
    45     void Action_123(LanSocket.ClientMsgUnPack msg)
    46     {
    47         long userID = msg.GetUserID();
    48         ushort accountLen = msg.ReadUShort();
    49         string account = msg.ReadString(accountLen);
    50         ushort passLen = msg.ReadUShort();
    51         string pass = msg.ReadString(passLen);
    52 
    53         print("Action_123 account: " + account + " pass word: " + pass+" from user: " + userID);
    54 
    55         LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();
    56         sendMsg.SetHead(123);
    57         string strAccount = "test account";
    58         sendMsg.Pack16bit((ushort)strAccount.Length);
    59         sendMsg.PackString(strAccount, (ushort)strAccount.Length);
    60         string strPass = "test pass word";
    61         sendMsg.Pack16bit((ushort)strPass.Length);
    62         sendMsg.PackString(strPass, (ushort)strPass.Length);
    63         sendMsg.PackEnd();
    64         LanSocket.Server.SendTo(ref sendMsg, msg.GetUserID());
    65     }
    66 }
    ServerMain.cs
     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class ClientMain : MonoBehaviour {
     5 
     6     // Use this for initialization
     7     void Start () 
     8     {
     9         LanSocket.Client.Start();    
    10     }
    11     
    12     // Update is called once per frame
    13     void Update ()
    14     {
    15         LanSocket.MsgUnPack msg = null;
    16         LanSocket.Client.GetMsg(ref msg);
    17         if(null != msg)
    18         {
    19             print("here have one msg on client");
    20         }
    21 
    22         if(Input.GetKeyUp(KeyCode.J))
    23         {
    24             LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();
    25             sendMsg.SetHead(123);
    26             string strAccount = "test account";
    27             sendMsg.Pack16bit((ushort)strAccount.Length);
    28             sendMsg.PackString(strAccount, (ushort)strAccount.Length);
    29             string strPass = "test pass word";
    30             sendMsg.Pack16bit((ushort)strPass.Length);
    31             sendMsg.PackString(strPass, (ushort)strPass.Length);
    32             sendMsg.PackEnd();
    33             LanSocket.Client.Send(ref sendMsg);
    34         }
    35     }
    36     void OnDestroy()
    37     {
    38         LanSocket.Client.Destroy();
    39     }
    40 }
    ClientMain.cs

    以上为全部代码,拖到u3d项目中,然后将clientmain或servermain挂在对象上就可以运行了

  • 相关阅读:
    8、【转载】python enhanced generator - coroutine
    7、【转载】python yield generator 详解
    7、利用SAX编写程序解析Yahoo的XML格式的天气预报,获取天气预报
    6、urllib.request.Request类
    5、urllib.request.urlopen()
    重载内核的一份代码的学习
    分析
    CVE-2014-0282
    IOS逆向【5】GDB调试helloworld
    IOS逆向【4】.ipa安装
  • 原文地址:https://www.cnblogs.com/saucerman/p/5549714.html
Copyright © 2020-2023  润新知