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挂在对象上就可以运行了

原文地址:https://www.cnblogs.com/saucerman/p/5549714.html