u3d局域网游戏网络(c# socket select 模型)——续

原文:http://www.cnblogs.com/saucerman/p/5555793.html

因为项目要加语音。语音数据都非常大。所以顺带就把之前写的网络模块一起测试了。

然后发现了一些bug,逐修。本来想在原文上面直接修改掉。但是恐怕已经看到的人拿去用了之后,再回头看也不一定能看明白,索性再写一文,将新文件直接放上来。

错误修改:

  1. 网络接收数据后,有一种情况没有处理完整,导致接收数据之后数据池的计数器没有向后偏移
  2. 网络数据处理后,当当前包仅剩1字节,下一个次数据进来的时候,需要2字节才能确认当前消息长度。增加了消息补齐机制。
  3. 增加了当网络数据拥堵的时候,直接断开当前链接。
  4. MsgUnPack的GetHead函数获取消息id的时候使用了错误的函数,导致数据偏移不正确
  5. MsgUnPack的UnPack(byte[] mBuff, ushort offset, ushort len),由于总buff扩大,导致offset参数超过上限,改为int
  6. 消息事件增加了错误消息ID过滤

由于语音的需求,将原本的服务器段接受buff容量扩大一倍。增加了语音模块。

特别说下语音模块。

http://blog.csdn.net/huutu/article/details/20216613

这是原文。

稍做修改。特别说一下这个语音模块在使用中容易遇到的问题。

  1. 如果声音太小,可能是你录音设备的侦听开得不够。
  2. 本地测试还好,放到网络上之后,因为代码里有处理,如果没有对象会创建对象并且添加必要组件。原文在创建的时候比特率是手动填写的。导致我客户端一个比特率,服务器一个比特率。然后客户端听着一切正常,传给服务器就错了。后来查了一天,排查各个代码段之后才找到这个原因。

以下是代码:

新增语音模块:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Text;
  6 using UnityEngine;
  7 using System.Collections;
  8 
  9 [RequireComponent(typeof(AudioSource))]
 10 public class MicroPhoneInput : MonoBehaviour
 11 {
 12 
 13     private static MicroPhoneInput m_instance;
 14 
 15     public float sensitivity = 100;
 16     public float loudness = 0;
 17 
 18     private static string[] micArray = null;
 19 
 20     const int HEADER_SIZE = 44;
 21 
 22     const int RECORD_TIME = 5;
 23     const int RECORD_frequency = 8000;
 24 
 25     // Use this for initialization  
 26     void Start()
 27     {
 28     }
 29 
 30     public static MicroPhoneInput getInstance()
 31     {
 32         if (m_instance == null)
 33         {
 34             micArray = Microphone.devices;
 35             if (micArray.Length == 0)
 36             {
 37                 Debug.LogError("Microphone.devices is null");
 38             }
 39             foreach (string deviceStr in Microphone.devices)
 40             {
 41                 Debug.Log("device name = " + deviceStr);
 42             }
 43             if (micArray.Length == 0)
 44             {
 45                 Debug.LogError("no mic device");
 46             }
 47 
 48             GameObject MicObj = new GameObject("MicObj");
 49             m_instance = MicObj.AddComponent<MicroPhoneInput>();
 50         }
 51         return m_instance;
 52     }
 53 
 54     public void StartRecord()
 55     {
 56         audio.Stop();
 57         if (micArray.Length == 0)
 58         {
 59             Debug.Log("No Record Device!");
 60             return;
 61         }
 62         audio.loop = false;
 63         audio.mute = true;
 64         audio.clip = Microphone.Start(null, false, RECORD_TIME, RECORD_frequency); //22050   
 65         while (!(Microphone.GetPosition(null) > 0))
 66         {
 67         }
 68         audio.Play();
 69         Debug.Log("StartRecord");
 70         //倒计时  
 71         StartCoroutine(TimeDown());
 72 
 73     }
 74 
 75     public void StopRecord()
 76     {
 77         if (micArray.Length == 0)
 78         {
 79             Debug.Log("No Record Device!");
 80             return;
 81         }
 82         if (!Microphone.IsRecording(null))
 83         {
 84             return;
 85         }
 86         Microphone.End(null);
 87         audio.Stop();
 88 
 89         Debug.Log("StopRecord");
 90 
 91     }
 92 
 93     public Byte[] GetClipData()
 94     {
 95         if (audio.clip == null)
 96         {
 97             Debug.Log("GetClipData audio.clip is null");
 98             return null;
 99         }
100 
101         float[] samples = new float[audio.clip.samples];
102 
103         audio.clip.GetData(samples, 0);
104 
105 
106         Byte[] outData = new byte[samples.Length * 2];
107         //Int16[] intData = new Int16[samples.Length];  
108         //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]  
109 
110         int rescaleFactor = 32767; //to convert float to Int16  
111 
112         for (int i = 0; i < samples.Length; i++)
113         {
114             short temshort = (short)(samples[i] * rescaleFactor);
115 
116             Byte[] temdata = System.BitConverter.GetBytes(temshort);
117 
118             outData[i * 2] = temdata[0];
119             outData[i * 2 + 1] = temdata[1];
120 
121 
122         }
123         if (outData == null || outData.Length <= 0)
124         {
125             Debug.Log("GetClipData intData is null");
126             return null;
127         }
128         //return intData;  
129         return outData;
130     }
131     public void PlayClipData(Int16[] intArr)
132     {
133         if (intArr.Length == 0)
134         {
135             Debug.Log("get intarr clipdata is null");
136             return;
137         }
138         //从Int16[]到float[]  
139         float[] samples = new float[intArr.Length];
140         int rescaleFactor = 32767;
141         for (int i = 0; i < intArr.Length; i++)
142         {
143             samples[i] = (float)intArr[i] / rescaleFactor;
144         }
145 
146         //从float[]到Clip  
147         AudioSource audioSource = this.GetComponent<AudioSource>();
148         if (audioSource.clip == null)
149         {
150             audioSource.clip = AudioClip.Create("playRecordClip", intArr.Length, 1, RECORD_frequency, false, false);
151         }
152         audioSource.clip.SetData(samples, 0);
153         audioSource.mute = false;
154         audioSource.Play();
155     }
156     public void PlayRecord()
157     {
158         if (audio.clip == null)
159         {
160             Debug.Log("audio.clip=null");
161             return;
162         }
163         audio.mute = false;
164         audio.loop = false;
165         audio.Play();
166         Debug.Log("PlayRecord");
167 
168     }
169 
170 
171 
172     public float GetAveragedVolume()
173     {
174         float[] data = new float[256];
175         float a = 0;
176         audio.GetOutputData(data, 0);
177         foreach (float s in data)
178         {
179             a += Mathf.Abs(s);
180         }
181         return a / 256;
182     }
183 
184     // Update is called once per frame  
185     void Update()
186     {
187 //         loudness = GetAveragedVolume() * sensitivity;
188 //         if (loudness > 1)
189 //         {
190 //             Debug.Log("loudness = " + loudness);
191 //         }
192     }
193 
194     private IEnumerator TimeDown()
195     {
196         Debug.Log(" IEnumerator TimeDown()");
197 
198         int time = 0;
199         while (time < RECORD_TIME)
200         {
201             if (!Microphone.IsRecording(null))
202             { //如果没有录制  
203                 Debug.Log("IsRecording false");
204                 yield break;
205             }
206             Debug.Log("yield return new WaitForSeconds " + time);
207             yield return new WaitForSeconds(1);
208             time++;
209         }
210         if (time >= 10)
211         {
212             Debug.Log("RECORD_TIME is out! stop record!");
213             StopRecord();
214         }
215         yield return 0;
216     }
217 }
MicroPhoneInput.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, long userID)
20         {
21             m_UserID = userID;
22             UnPack(mBuff, len);
23         }
24 
25         public ClientMsgUnPack(byte[] mBuff, int offset, ushort len, long 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 ServerEventDelagate(LanSocket.ClientMsgUnPack msg);
  6 
  7 class EventNode
  8 {
  9     public int m_EventID;
 10     public LanSocket.ClientMsgUnPack msg;
 11 }
 12 
 13 class EventDispathBase
 14 {
 15     public static int g_MaxEventNum = 300;
 16 }
 17 
 18 class ServerEventDispath : EventDispathBase
 19 {
 20     List<ServerEventDelagate>[] m_Event;
 21     Queue<EventNode> m_EventQueue;
 22     public ServerEventDispath()
 23     {
 24         m_Event = new List<ServerEventDelagate>[g_MaxEventNum];
 25         m_EventQueue = new Queue<EventNode>();
 26     }
 27 
 28     public void RegistEvent(int eventID, ServerEventDelagate func)
 29     {
 30         if(null == m_Event[eventID])
 31         {
 32             m_Event[eventID] = new List<ServerEventDelagate>();
 33         }
 34         m_Event[eventID].Add(func);
 35     }
 36 
 37     public void AddEvent(EventNode eventNode)
 38     {
 39         m_EventQueue.Enqueue(eventNode);
 40     }
 41 
 42     public void Proccess()
 43     {
 44         if (0 != m_EventQueue.Count)
 45         {
 46             EventNode mCur = m_EventQueue.Dequeue();
 47             if (mCur.m_EventID >= g_MaxEventNum || mCur.m_EventID < 0)
 48             {
 49                 MonoBehaviour.print("error event ID: " + mCur.m_EventID);
 50                 return;
 51             }
 52             if (null == m_Event[mCur.m_EventID])
 53             {
 54                 MonoBehaviour.print("event ID: "+ mCur.m_EventID+" is null");
 55             }
 56             else
 57             {
 58                 List<ServerEventDelagate> curEventDelagate = m_Event[mCur.m_EventID];
 59                 for(int i = 0 ; i < curEventDelagate.Count ; ++i)
 60                 {
 61                     curEventDelagate[i](mCur.msg);
 62                 }
 63             }
 64         }
 65     }
 66 }
 67 
 68 
 69 delegate void ClientEventDelagate(LanSocket.MsgUnPack msg);
 70 class ClientEventDispath : EventDispathBase
 71 {
 72     List<ClientEventDelagate>[] m_Event;
 73     Queue<EventNode> m_EventQueue;
 74     public ClientEventDispath()
 75     {
 76         m_Event = new List<ClientEventDelagate>[g_MaxEventNum];
 77         m_EventQueue = new Queue<EventNode>();
 78     }
 79 
 80     public void RegistEvent(int eventID, ClientEventDelagate func)
 81     {
 82         if (null == m_Event[eventID])
 83         {
 84             m_Event[eventID] = new List<ClientEventDelagate>();
 85         }
 86         m_Event[eventID].Add(func);
 87     }
 88 
 89     public void AddEvent(EventNode eventNode)
 90     {
 91         m_EventQueue.Enqueue(eventNode);
 92     }
 93 
 94     public void Proccess()
 95     {
 96         if (0 != m_EventQueue.Count)
 97         {
 98             EventNode mCur = m_EventQueue.Dequeue();
 99             if (mCur.m_EventID >= g_MaxEventNum || mCur.m_EventID < 0)
100             {
101                 MonoBehaviour.print("error event ID: " + mCur.m_EventID);
102                 return;
103             }
104             if (null == m_Event[mCur.m_EventID])
105             {
106                 MonoBehaviour.print("event ID: " + mCur.m_EventID + " is null");
107             }
108             else
109             {
110                 List<ClientEventDelagate> curEventDelagate = m_Event[mCur.m_EventID];
111                 for (int i = 0; i < curEventDelagate.Count; ++i)
112                 {
113                     curEventDelagate[i](mCur.msg);
114                 }
115             }
116         }
117     }
118 }
EventDispath.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 * 100;
18         public static int m_HeadSize = 6;
19         protected bool m_HasInit = false;
20         private Mutex m_Mutex;
21 
22         public void BaseInit()
23         {
24             m_HasInit = true;
25             m_Mutex = new Mutex();
26         }
27 
28         public void BaseRelease()
29         {
30             m_Mutex.Close();
31         }
32 
33         protected void Lock()
34         {
35             m_Mutex.WaitOne();
36             //MonoBehaviour.print("Lock:" + Thread.CurrentThread.ManagedThreadId.ToString());
37         }
38 
39         protected void UnLock()
40         {
41             m_Mutex.ReleaseMutex();
42             //MonoBehaviour.print("Unlock:" + Thread.CurrentThread.ManagedThreadId.ToString());
43         }
44     }
45 }
LanSocketBase.cs
  1 using UnityEngine;
  2 /*
  3  * 通信协议
  4  * 消息头前2字节保存当前消息长度
  5  * 后面跟4字节表示消息ID
  6  * 再后面是消息实质内容
  7  */
  8 
  9 namespace LanSocket
 10 {
 11     public class MsgPack : PackBase
 12     {
 13         public MsgPack()
 14         {
 15             m_OnePackIndex = LanSocketBase.m_HeadSize;
 16         }
 17 
 18         public void SetHead(int ID)
 19         {
 20             byte[] mBuff = System.BitConverter.GetBytes(ID);
 21             System.Buffer.BlockCopy(mBuff, 0, m_OnePack, 2, 4);
 22         }
 23 
 24         public void PackEnd()
 25         {
 26             byte[] mBuff = System.BitConverter.GetBytes(m_OnePackIndex);
 27             System.Buffer.BlockCopy(mBuff, 0, m_OnePack, 0, 2);
 28         }
 29 
 30         public void Packbool(bool data)
 31         {
 32             ushort curDatalen = 1;
 33             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
 34             {
 35                 MonoBehaviour.print("Packbool() longer lager than Max buff len");
 36                 return;
 37             }
 38             byte[] mBuff = System.BitConverter.GetBytes(data);
 39             Pack(mBuff, curDatalen);
 40         }
 41 
 42         public void Pack16bit(short data)
 43         {
 44             ushort curDatalen = 2;
 45             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
 46             {
 47                 MonoBehaviour.print("Pack16bit(short) longer lager than Max buff len");
 48                 return;
 49             }
 50             byte[] mBuff = System.BitConverter.GetBytes(data);
 51             Pack(mBuff, curDatalen);
 52         }
 53         public void Pack16bit(ushort data)
 54         {
 55             ushort curDatalen = 2;
 56             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
 57             {
 58                 MonoBehaviour.print("Pack16bit(ushort) longer lager than Max buff len");
 59                 return;
 60             }
 61             byte[] mBuff = System.BitConverter.GetBytes(data);
 62             Pack(mBuff, curDatalen);
 63         }
 64         public void Pack32bit(int data)
 65         {
 66             ushort curDatalen = 4;
 67             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
 68             {
 69                 MonoBehaviour.print("Pack32bit(int) longer lager than Max buff len");
 70                 return;
 71             }
 72             byte[] mBuff = System.BitConverter.GetBytes(data);
 73             Pack(mBuff, curDatalen);
 74         }
 75         public void Pack32bit(uint data)
 76         {
 77             ushort curDatalen = 4;
 78             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
 79             {
 80                 MonoBehaviour.print("Pack32bit(uint) longer lager than Max buff len");
 81                 return;
 82             }
 83             byte[] mBuff = System.BitConverter.GetBytes(data);
 84             Pack(mBuff, curDatalen);
 85         }
 86         public void Pack32bit(float data)
 87         {
 88             ushort curDatalen = 4;
 89             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
 90             {
 91                 MonoBehaviour.print("Pack32bit(float) longer lager than Max buff len");
 92                 return;
 93             }
 94             byte[] mBuff = System.BitConverter.GetBytes(data);
 95             Pack(mBuff, curDatalen);
 96         }
 97         public void Pack64bit(double data)
 98         {
 99             ushort curDatalen = 8;
100             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
101             {
102                 MonoBehaviour.print("Pack64bit(double) longer lager than Max buff len");
103                 return;
104             }
105             byte[] mBuff = System.BitConverter.GetBytes(data);
106             Pack(mBuff, curDatalen);
107         }
108         public void Pack64bit(long data)
109         {
110             ushort curDatalen = 8;
111             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
112             {
113                 MonoBehaviour.print("Pack64bit(long) longer lager than Max buff len");
114                 return;
115             }
116             byte[] mBuff = System.BitConverter.GetBytes(data);
117             Pack(mBuff, curDatalen);
118         }
119 
120         public void PackString(string data, ushort len)
121         {
122             ushort curDatalen = len;
123             if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
124             {
125                 MonoBehaviour.print("PackString() longer lager than Max buff len");
126                 return;
127             }
128             byte[] mBuff = System.Text.Encoding.UTF8.GetBytes(data);
129             Pack(mBuff, curDatalen);
130         }
131 
132         public void PackByte(byte[] data, int offset, ushort len)
133         {
134             if (m_OnePackIndex + len > m_MaxOnePackBuff)
135             {
136                 MonoBehaviour.print("PackByte() longer lager than Max buff len");
137                 return;
138             }
139             System.Buffer.BlockCopy(data, offset, m_OnePack, m_OnePackIndex, len);
140             m_OnePackIndex += len;
141         }
142 
143         void Pack(byte[] data, ushort len)
144         {
145             System.Buffer.BlockCopy(data, 0, m_OnePack, m_OnePackIndex, len);
146             m_OnePackIndex += len;
147         }
148 
149         public byte[] GetByte()
150         {
151             return m_OnePack;
152         }
153 
154         public int GetByteLen()
155         {
156             return m_OnePackIndex;
157         }
158     }
159 }
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.ToInt32(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, int 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, int 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 byte[] ReadByte(ushort len)
169         {
170             byte[] mCur = null;
171             if (m_OnePackIndex + len > m_PackLen)
172             {
173                 MonoBehaviour.print("ReadByte() longer lager than Max buff len");
174                 return mCur;
175             }
176             mCur = new byte[len];
177             System.Buffer.BlockCopy(m_OnePack, m_OnePackIndex, mCur, 0, len);
178             m_OnePackIndex += len;
179             return mCur;
180         }
181 
182         public int GetMsgID()
183         {
184             return m_MsgID;
185         }
186     }
187 }
MsgUnPack.cs
 1 using System.Threading;
 2 
 3 /*
 4  *轻量级局域网服务器。 
 5  * 协议如下
 6  * 消息头前2字节保存当前消息长度
 7  * 后面跟4字节表示消息ID
 8  * 再后面是消息实质内容
 9  */
10 
11 namespace LanSocket
12 {
13     public class PackBase
14     {
15         protected int m_MaxOnePackBuff;
16         protected byte[] m_OnePack;
17         protected int m_OnePackIndex;
18 
19         public PackBase()
20         {
21             m_MaxOnePackBuff = LanSocketBase.m_MaxOnePackBuff;
22             m_OnePack = new byte[m_MaxOnePackBuff];
23             m_OnePackIndex = 0;
24         }
25     }
26 }
PackBase.cs
 1 using System.Net.Sockets;
 2 using System.Threading;
 3 using System.Net;
 4 
 5 public class SocketBase
 6 {
 7     protected bool m_HasInit = false;
 8     protected Socket m_Socket;
 9     protected Thread m_LinstenThread;
10     protected IPEndPoint m_IP;
11     protected Mutex m_Mutex;
12 }
SocketBase.cs
 1 using UnityEngine;
 2 using System.Net.Sockets;
 3 using System.Net;
 4 using System.Threading;
 5 using System.Collections.Generic;
 6 
 7 class ReciveBroadcast : SocketBase
 8 {
 9     public Queue<string> m_ServerIP;
10     public void Start(int port)
11     {
12         if (m_HasInit)
13         {
14             return;
15         }
16         try
17         {
18             m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
19             m_IP = new IPEndPoint(IPAddress.Any, port);
20             m_Socket.Bind(m_IP);
21             MonoBehaviour.print("广播网络启动监听" + m_Socket.LocalEndPoint.ToString());
22             m_LinstenThread = new Thread(ListenClientConnect);
23             m_LinstenThread.Start();
24             m_ServerIP = new Queue<string>();
25             m_Mutex = new Mutex();
26             m_HasInit = true;
27         }
28         catch (System.Exception ex)
29         {
30             MonoBehaviour.print("Broadcast reciver Start catch:" + ex.Message);
31         }
32     }
33 
34     void ListenClientConnect()
35     {
36         EndPoint ep = (EndPoint)m_IP;
37         try
38         {
39             while (true)
40             {
41                 Thread.Sleep(1);
42                 byte[] data = new byte[64];
43                 int recv = m_Socket.ReceiveFrom(data, ref ep);
44                 string stringData = System.Text.Encoding.UTF8.GetString(data, 0, recv);
45                 m_Mutex.WaitOne();
46                 m_ServerIP.Enqueue(stringData);
47                 m_Mutex.ReleaseMutex();
48                 MonoBehaviour.print("received: " + stringData + " from: " + ep.ToString());
49             }
50         }
51         catch (System.Exception ex)
52         {
53             MonoBehaviour.print("Broadcast reciver ListenClientConnect out:" + ex.Message);
54         }
55     }
56 
57     public void Destroy()
58     {
59         if (!m_HasInit)
60         {
61             return;
62         }
63         m_Socket.Close();
64         m_LinstenThread.Abort();
65     }
66 
67     public string GetIP()
68     {
69         if (!m_HasInit)
70         {
71             return "";
72         }
73 
74         try
75         {
76             m_Mutex.WaitOne();
77             if (0 != m_ServerIP.Count)
78             {
79                 m_Mutex.ReleaseMutex();
80                 return m_ServerIP.Dequeue();
81             }
82             m_Mutex.ReleaseMutex();
83         }
84         catch (System.Exception ex)
85         {
86             MonoBehaviour.print("Broadcast GetIP catch:" + ex.Message);
87             return "";
88         }
89         return "";
90     }
91 }
ReciveBroadcast.cs
 1 using UnityEngine;
 2 using System.Net.Sockets;
 3 using System.Net;
 4 
 5 class SendBroadcast : SocketBase
 6 {
 7     byte[] m_MyIP;
 8     public void Start(int port)
 9     {
10         if (m_HasInit)
11         {
12             return;
13         }
14         try
15         {
16             m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
17             m_IP = new IPEndPoint(IPAddress.Broadcast, port);//255.255.255.255
18             //m_IP = new IPEndPoint(IPAddress.Parse("192.168.255.255"), 9050);
19 
20             string mLocalIP = "";
21             string hostname = Dns.GetHostName();
22             IPHostEntry localHost = Dns.GetHostEntry(hostname);
23             for (int i = 0; i < localHost.AddressList.Length; ++i)
24             {
25                 if (localHost.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
26                 {
27                     //MonoBehaviour.print(localHost.AddressList[i].ToString());
28                     mLocalIP = localHost.AddressList[i].ToString();
29                     break;
30                 }
31             }
32 
33             if ("".Equals(m_MyIP))
34             {
35                 MonoBehaviour.print("网络检测异常。请检查网络设置或接入网络");
36                 m_Socket.Close();
37                 m_Socket = null;
38                 return;
39             }
40             m_MyIP = System.Text.Encoding.UTF8.GetBytes(mLocalIP);
41             m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
42             m_HasInit = true;
43         }
44         catch (System.Exception ex)
45         {
46             MonoBehaviour.print("Broadcast sender Start catch:" + ex.Message);
47         }
48     }
49 
50     public void Send()
51     {
52         if(null != m_Socket)
53         {
54             MonoBehaviour.print("send a broadcast");
55             m_Socket.SendTo(m_MyIP, m_IP);
56         }
57     }
58 
59     public void Destroy()
60     {
61         if (!m_HasInit)
62         {
63             return;
64         }
65         m_Socket.Close();
66     }
67 }
SendBroadcast.cs
  1 using System.Net.Sockets;
  2 using System.Net;
  3 using System.Threading;
  4 using UnityEngine;
  5 using System.Collections.Generic;
  6 
  7 /*
  8  *轻量级局域网服务器。 
  9  * 协议如下
 10  * 消息头前2字节保存当前消息长度
 11  * 后面跟4字节表示消息ID
 12  * 再后面是消息实质内容
 13  */
 14 
 15 namespace LanSocket
 16 {
 17     class Client : LanSocketBase
 18     {
 19         Thread m_ReciveThread;
 20         Socket m_Connect;
 21         byte[] m_AllData;
 22         int m_AllDataHead;
 23         int m_AllDataEnd;
 24         int m_MsgNum;
 25         byte[] m_OnePack;
 26         int m_OnePackIndex;
 27 
 28         public void Start(string strIP, int port)
 29         {
 30             if (m_HasInit)
 31             {
 32                 return;
 33             }
 34             //设定服务器IP地址  
 35             IPAddress ip = IPAddress.Parse(strIP);
 36             Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 37             try
 38             {
 39                 temp.Connect(new IPEndPoint(ip, port)); //配置服务器IP与端口  
 40                 MonoBehaviour.print("连接服务器成功");
 41 
 42                 BaseInit();
 43                 m_Connect = temp;
 44                 m_ReciveThread = new Thread(ReceiveMessage);
 45                 m_ReciveThread.Start();
 46                 m_AllData = new byte[LanSocketBase.m_MaxAllBuff + 1];
 47                 m_AllDataHead = 0;
 48                 m_AllDataEnd = 0;
 49                 m_MsgNum = 0;
 50                 m_OnePack = new byte[m_MaxOnePackBuff + 1];
 51                 m_OnePackIndex = 0;
 52             }
 53             catch (System.Exception ex)
 54             {
 55                 MonoBehaviour.print("连接服务器失败: " + ex.Message);
 56                 return;
 57             }
 58         }
 59 
 60         private void PutDataToBuff(byte[] mClientSendBuff, int mReceiveNumber)
 61         {
 62             if (m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff)
 63             {
 64                 byte[] mCurAllData = new byte[m_AllDataEnd - m_AllDataHead];
 65                 System.Buffer.BlockCopy(m_AllData, m_AllDataHead, mCurAllData, 0, m_AllDataEnd - m_AllDataHead);
 66                 System.Buffer.BlockCopy(mCurAllData, 0, m_AllData, 0, m_AllDataEnd - m_AllDataHead);
 67                 m_AllDataEnd -= m_AllDataHead;
 68                 m_AllDataHead = 0;
 69             }
 70             int mOnePackStartPos = 0;
 71             while (mReceiveNumber > 0)
 72             {
 73                 if (0 == m_OnePackIndex)
 74                 {
 75                     ushort datalen = System.BitConverter.ToUInt16(mClientSendBuff, mOnePackStartPos);
 76                     if (datalen <= mReceiveNumber)
 77                     {
 78                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_AllData, m_AllDataEnd, datalen);
 79                         m_AllDataEnd += datalen;
 80 
 81                         mOnePackStartPos += datalen;
 82 
 83                         mReceiveNumber -= datalen;
 84                         ++m_MsgNum;
 85                     }
 86                     else
 87                     {
 88                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);
 89                         m_OnePackIndex += mReceiveNumber;
 90                         mOnePackStartPos += mReceiveNumber;
 91 
 92                         mReceiveNumber -= mReceiveNumber;
 93                     }
 94                 }
 95                 else
 96                 {
 97                     if (m_OnePackIndex < 2)
 98                     {
 99                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, 1);
100 
101                         ++m_OnePackIndex;
102                         --mReceiveNumber;
103                         ++mOnePackStartPos;
104                     }
105                     ushort datalen = System.BitConverter.ToUInt16(m_OnePack, 0);
106                     if (m_OnePackIndex + mReceiveNumber >= datalen)
107                     {
108                         int mNeedNum = datalen - m_OnePackIndex;
109                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mNeedNum);
110                         mOnePackStartPos += mNeedNum;
111                         
112                         System.Buffer.BlockCopy(m_OnePack, 0, m_AllData, m_AllDataEnd, datalen);
113                         m_OnePackIndex = 0;
114                         m_AllDataEnd += datalen;
115 
116                         mReceiveNumber -= mNeedNum;
117                     }
118                     else
119                     {
120                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);
121                         m_OnePackIndex += mReceiveNumber;
122                         mOnePackStartPos += mReceiveNumber;
123 
124                         mReceiveNumber -= mReceiveNumber;
125                     }
126                 }
127             }
128         }
129 
130         public void Destroy()
131         {
132             if (!m_HasInit)
133             {
134                 return;
135             }
136             BaseRelease();
137             ShutDownConnect();
138             m_MsgNum = 0;
139         }
140 
141         public void GetMsg(ref MsgUnPack msg)
142         {
143             if (!m_HasInit)
144             {
145                 return;
146             }
147             try
148             {
149                 Lock();
150                 if (0 != m_MsgNum)
151                 {
152                     ushort datalen = System.BitConverter.ToUInt16(m_AllData, m_AllDataHead);
153                     msg = new MsgUnPack(m_AllData, (ushort)m_AllDataHead, (ushort)datalen);
154                     m_AllDataHead += datalen;
155                     --m_MsgNum;
156                 }
157             }
158             finally
159             {
160                 UnLock();
161             }
162         }
163 
164         /// <summary>  
165         /// 接收消息  
166         /// </summary>  
167         public void ReceiveMessage()
168         {
169             while (true)
170             {
171                 Thread.Sleep(1);
172                 try
173                 {
174                     //通过clientSocket接收数据  
175                     byte[] mClientSendBuff = new byte[m_MaxOnePackBuff + 1];
176                     int mReceiveNumber = m_Connect.Receive(mClientSendBuff);
177                     if (0 == mReceiveNumber)
178                     {
179                         MonoBehaviour.print("disconnect");
180                         ShutDownConnect();
181                     }
182                     else if (mReceiveNumber > 0)
183                     {
184                         try
185                         {
186                             Lock();
187                             PutDataToBuff(mClientSendBuff, mReceiveNumber);
188                         }
189                         catch (System.Exception ex)
190                         {
191                             MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);
192                         }
193                         finally
194                         {
195                             UnLock();
196                         }
197                     }
198                     else
199                     {
200                         MonoBehaviour.print("one connect recive a error num: " + mReceiveNumber.ToString());
201                     }
202                 }
203                 catch (System.Exception ex)
204                 {
205                     MonoBehaviour.print("ReceiveMessage catch: " + ex.Message);
206                     ShutDownConnect();
207                 }
208             }
209         }
210 
211         public void Send(ref MsgPack msg)
212         {
213             try
214             {
215                 Lock();
216                 m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
217             }
218             finally
219             {
220                 UnLock();
221             }
222         }
223 
224         public void ShutDownConnect()
225         {
226             m_ReciveThread.Abort();
227             if (m_Connect.Connected)
228             {
229                 m_Connect.Shutdown(SocketShutdown.Both);
230             }
231             m_Connect.Close();
232         }
233     }
234 }
SocketClient.cs
  1 using System.Net.Sockets;
  2 using System.Net;
  3 using System.Threading;
  4 using UnityEngine;
  5 using System.Collections.Generic;
  6 /*
  7  *轻量级局域网服务器。 
  8  * 协议如下
  9  * 消息头前2字节保存当前消息长度
 10  * 后面跟4字节表示消息ID
 11  * 再后面是消息实质内容
 12  */
 13 
 14 namespace LanSocket
 15 {
 16     class ClientConnect
 17     {
 18         public byte[] m_AllData;
 19         public int m_AllDataHead;
 20         public int m_AllDataEnd;
 21         public int m_MsgCount;
 22         public byte[] m_OnePack;
 23         public int m_OnePackIndex;
 24         public Socket m_Connect;
 25         public long m_UserID;
 26 
 27         public ClientConnect()
 28         {
 29             m_AllData = new byte[LanSocketBase.m_MaxAllBuff];
 30             m_AllDataHead = 0;
 31             m_AllDataEnd = 0;
 32             m_MsgCount = 0;
 33             m_OnePack = new byte[LanSocketBase.m_MaxOnePackBuff];
 34             m_OnePackIndex = 0;
 35             m_Connect = null;
 36             m_UserID = 0;
 37         }
 38 
 39         public void Reset()
 40         {
 41             m_AllDataHead = 0;
 42             m_AllDataEnd = 0;
 43             m_MsgCount = 0;
 44             m_OnePackIndex = 0;
 45             m_Connect = null;
 46             m_UserID = 0;
 47         }
 48     }
 49     class Server : LanSocketBase
 50     {
 51         Queue<int> m_MsgOrder;
 52 
 53         Socket m_ServerSocket;
 54         Thread m_LinstenThread;
 55         Thread m_ReciveThread;
 56         System.Collections.ArrayList m_ServerSocketList;
 57         System.Collections.ArrayList m_listenSocketList;
 58         System.Collections.ArrayList m_DeleteSocketList;
 59         int m_MaxClientConnect = 10;
 60         ClientConnect[] m_ConnectPool;
 61         Queue<int> m_EmptyConnect;
 62         public void Start(int port)
 63         {
 64             if (m_HasInit)
 65             {
 66                 return;
 67             }
 68             string mLocalIP = "";
 69 
 70             string mHostName = Dns.GetHostName();
 71             IPHostEntry localHost = Dns.GetHostEntry(mHostName);
 72             for (int i = 0; i < localHost.AddressList.Length; ++i)
 73             {
 74                 if (localHost.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
 75                 {
 76                     //MonoBehaviour.print(localHost.AddressList[i].ToString());
 77                     mLocalIP = localHost.AddressList[i].ToString();
 78                     break;
 79                 }
 80             }
 81 
 82             if ("".Equals(mLocalIP))
 83             {
 84                 MonoBehaviour.print("网络检测异常。请检查网络设置或接入网络");
 85                 return;
 86             }
 87             BaseInit();
 88             m_MsgOrder = new Queue<int>();
 89 
 90             //服务器IP地址  
 91             IPAddress ip = IPAddress.Parse(mLocalIP);
 92             m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 93             m_ServerSocket.Bind(new IPEndPoint(ip, port));  //绑定IP地址:端口  
 94             m_ServerSocket.Listen(10);    //设定最多10个排队连接请求  
 95             MonoBehaviour.print("游戏网络启动监听" + m_ServerSocket.LocalEndPoint.ToString());
 96 
 97             m_ServerSocketList = new System.Collections.ArrayList();
 98             m_listenSocketList = new System.Collections.ArrayList();
 99             m_DeleteSocketList = new System.Collections.ArrayList();
100 
101             m_ConnectPool = new ClientConnect[m_MaxClientConnect];
102             m_EmptyConnect = new Queue<int>();
103             for (int i = 0; i < m_MaxClientConnect; ++i)
104             {
105                 m_ConnectPool[i] = new ClientConnect();
106                 m_EmptyConnect.Enqueue(i);
107             }
108             //通过Clientsoket发送数据  
109             m_ReciveThread = new Thread(ReceiveMessage);
110             m_ReciveThread.Start();
111             m_LinstenThread = new Thread(ListenClientConnect);
112             m_LinstenThread.Start();
113         }
114 
115         /// <summary>  
116         /// 监听客户端连接  
117         /// </summary>  
118         public void ListenClientConnect()
119         {
120             while (true)
121             {
122                 Thread.Sleep(500);
123                 m_ServerSocketList.Add(m_ServerSocket);
124                 Socket.Select(m_ServerSocketList, null, null, 1000);
125                 for (int i = 0; i < m_ServerSocketList.Count; ++i)
126                 {
127                     Socket clientSocket = ((Socket)m_ServerSocketList[i]).Accept();
128                     if (null != clientSocket)
129                     {
130                         try
131                         {
132                             Lock();
133                             if (0 == m_EmptyConnect.Count)
134                             {
135                                 MonoBehaviour.print("链接已经达到最大上线,丢弃当前连接");
136                                 clientSocket.Shutdown(SocketShutdown.Both);
137                                 clientSocket.Close();
138                             }
139                             else
140                             {
141                                 //m_listenSocketList.Add(clientSocket);
142                                 int mSlot = m_EmptyConnect.Dequeue();
143                                 m_ConnectPool[mSlot].m_Connect = clientSocket;
144                                 m_ConnectPool[mSlot].m_UserID = System.DateTime.Now.ToFileTime();
145                                 MonoBehaviour.print("成功连接一个客户端,编号:" + mSlot.ToString());
146                             }
147                         }
148                         finally
149                         {
150                             UnLock();
151                         }
152                     }
153                 }
154                 m_ServerSocketList.Clear();
155             }
156         }
157 
158         private bool PutDataToBuff(byte[] mClientSendBuff, int mReceiveNumber, Socket client)
159         {
160             ClientConnect curPlayer = null;
161             int mSlot = -1;
162             for (int i = 0; i < m_MaxClientConnect; ++i)
163             {
164                 if (client == m_ConnectPool[i].m_Connect)
165                 {
166                     curPlayer = m_ConnectPool[i];
167                     mSlot = i;
168                     break;
169                 }
170             }
171             if (null == curPlayer)
172             {
173                 return false;
174             }
175             if (curPlayer.m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff)
176             {
177                 byte[] mCurAllData = new byte[curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead];
178                 System.Buffer.BlockCopy(curPlayer.m_AllData, curPlayer.m_AllDataHead, mCurAllData, 0, curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead);
179                 System.Buffer.BlockCopy(mCurAllData, 0, curPlayer.m_AllData, 0, curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead);
180                 curPlayer.m_AllDataEnd -= curPlayer.m_AllDataHead;
181                 curPlayer.m_AllDataHead = 0;
182 
183                 if(curPlayer.m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff)
184                 {
185                     return false;
186                 }
187             }
188             int mOnePackStartPos = 0;
189             while (mReceiveNumber > 0)
190             {
191                 if (0 == curPlayer.m_OnePackIndex)
192                 {
193                     ushort datalen = System.BitConverter.ToUInt16(mClientSendBuff, mOnePackStartPos);
194                     if (datalen > LanSocketBase.m_MaxOnePackBuff || datalen < LanSocketBase.m_HeadSize)
195                     {
196                         return false;
197                     }
198                     if (datalen <= mReceiveNumber)
199                     {
200                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_AllData, curPlayer.m_AllDataEnd, datalen);
201                         curPlayer.m_AllDataEnd += datalen;
202                         mOnePackStartPos += datalen;
203 
204                         mReceiveNumber -= datalen;
205 
206                         m_MsgOrder.Enqueue(mSlot);
207                     }
208                     else
209                     {
210                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_OnePack, curPlayer.m_OnePackIndex, mReceiveNumber);
211                         curPlayer.m_OnePackIndex += mReceiveNumber;
212                         mOnePackStartPos += mReceiveNumber;
213 
214                         mReceiveNumber -= mReceiveNumber;
215                     }
216                 }
217                 else
218                 {
219                     if(curPlayer.m_OnePackIndex < 2)
220                     {
221                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_OnePack, curPlayer.m_OnePackIndex, 1);
222 
223                         ++curPlayer.m_OnePackIndex;
224                         --mReceiveNumber;
225                         ++mOnePackStartPos;
226                     }
227                     ushort datalen = System.BitConverter.ToUInt16(curPlayer.m_OnePack, 0);
228                     if (datalen > LanSocketBase.m_MaxOnePackBuff || datalen < LanSocketBase.m_HeadSize)
229                     {
230                         return false;
231                     }
232                     if (curPlayer.m_OnePackIndex + mReceiveNumber >= datalen)
233                     {
234                         int mNeedNum = datalen - curPlayer.m_OnePackIndex;
235                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_OnePack, curPlayer.m_OnePackIndex, mNeedNum);
236                         mOnePackStartPos += mNeedNum;
237 
238                         System.Buffer.BlockCopy(curPlayer.m_OnePack, 0, curPlayer.m_AllData, curPlayer.m_AllDataEnd, datalen);
239                         curPlayer.m_OnePackIndex = 0;
240                         curPlayer.m_AllDataEnd += datalen;
241 
242                         mReceiveNumber -= mNeedNum;
243 
244                         m_MsgOrder.Enqueue(mSlot);
245                     }
246                     else
247                     {
248                         System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_OnePack, curPlayer.m_OnePackIndex, mReceiveNumber);
249                         curPlayer.m_OnePackIndex += mReceiveNumber;
250                         mOnePackStartPos += mReceiveNumber;
251 
252                         mReceiveNumber -= mReceiveNumber;
253                     }
254                 }
255             }
256 
257             return true;
258         }
259 
260         /// <summary>  
261         /// 接收消息  
262         /// </summary>  
263         public void ReceiveMessage()
264         {
265             try
266             {
267                 while (true)
268                 {
269                     Thread.Sleep(1);
270                     for (int i = 0; i < m_MaxClientConnect; ++i)
271                     {
272                         if (null != m_ConnectPool[i].m_Connect)
273                         {
274                             m_listenSocketList.Add(m_ConnectPool[i].m_Connect);
275                         }
276                     }
277                     if (0 == m_listenSocketList.Count)
278                     {
279                         continue;
280                     }
281                     Socket.Select(m_listenSocketList, null, null, 1000);
282                     for (int i = 0; i < m_listenSocketList.Count; ++i)
283                     {
284                         Socket mClient = (Socket)m_listenSocketList[i];
285                         //try
286                         //{
287                         //通过clientSocket接收数据  
288                         byte[] mClientSendBuff = new byte[m_MaxOnePackBuff];
289                         int mReceiveNumber = mClient.Receive(mClientSendBuff);
290                         if (0 == mReceiveNumber)
291                         {
292                             m_DeleteSocketList.Add(mClient);
293                         }
294                         else if (mReceiveNumber > 0)
295                         {
296                             try
297                             {
298                                 Lock();
299                                 bool rt = PutDataToBuff(mClientSendBuff, mReceiveNumber, mClient);
300                                 if (!rt)
301                                 {
302                                     m_DeleteSocketList.Add(mClient);
303                                 }
304                             }
305                             catch (System.Exception ex)
306                             {
307                                 MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);
308                             }
309                             finally
310                             {
311                                 UnLock();
312                             }
313                         }
314                         else
315                         {
316                             MonoBehaviour.print("one connect recive a error num: " + mReceiveNumber.ToString());
317                         }
318                         //}
319                         //catch (System.Exception ex)
320                         //{
321                         //    MonoBehaviour.print("ReceiveMessage catch: " + ex.Message);
322                         //    m_DeleteSocketList.Add(mClient);
323                         //}
324                     }
325                     m_listenSocketList.Clear();
326                     if (0 != m_DeleteSocketList.Count)
327                     {
328                         ShutDownConnect();
329                     }
330                 }
331 
332             }
333             catch (System.Exception ex)
334             {
335                 MonoBehaviour.print("ReceiveMessage out:" + ex.Message);
336             }
337 
338         }
339 
340         /// <summary>  
341         /// 程序退出销毁  
342         /// </summary>  
343         public void Destroy()
344         {
345             if (!m_HasInit)
346             {
347                 return;
348             }
349             m_LinstenThread.Abort();
350             m_ReciveThread.Abort();
351             m_listenSocketList.Clear();
352 
353             for (int i = 0; i < m_ServerSocketList.Count; ++i)
354             {
355                 Socket mServer = (Socket)m_ServerSocketList[i];
356                 if (mServer.Connected)
357                 {
358                     mServer.Shutdown(SocketShutdown.Both);
359                 }
360                 mServer.Close();
361             }
362             m_ServerSocketList.Clear();
363 
364             for (int i = 0; i < m_MaxClientConnect; ++i)
365             {
366                 if (null != m_ConnectPool[i].m_Connect)
367                 {
368                     if (m_ConnectPool[i].m_Connect.Connected)
369                     {
370                         m_ConnectPool[i].m_Connect.Shutdown(SocketShutdown.Both);
371                     }
372                     m_ConnectPool[i].m_Connect.Close();
373                     m_ConnectPool[i].m_Connect = null;
374                 }
375             }
376             m_EmptyConnect.Clear();
377             BaseRelease();
378         }
379 
380         /// <summary>  
381         /// 销毁一个连接  
382         /// </summary>  
383         void ShutDownConnect()
384         {
385             try
386             {
387                 Lock();
388                 for (int j = 0; j < m_DeleteSocketList.Count; ++j)
389                 {
390                     Socket connect = (Socket)m_DeleteSocketList[j];
391                     for (int i = 0; i < m_MaxClientConnect; ++i)
392                     {
393                         if (connect == m_ConnectPool[i].m_Connect)
394                         {
395                             connect.Shutdown(SocketShutdown.Both);
396                             connect.Close();
397                             m_ConnectPool[i].Reset();
398                             m_EmptyConnect.Enqueue(i);
399                             MonoBehaviour.print("关闭一个连接,编号:" + i.ToString());
400                             break;
401                         }
402                     }
403                 }
404             }
405             catch (System.Exception ex)
406             {
407                 MonoBehaviour.print("ShutDownConnect catch: " + ex.Message);
408             }
409             finally
410             {
411                 m_DeleteSocketList.Clear();
412                 UnLock();
413             }
414         }
415 
416         /// <summary>  
417         /// 获取一个数据  
418         /// </summary>  
419         public void GetMsg(ref ClientMsgUnPack msg)
420         {
421             if(!m_HasInit)
422             {
423                 return;
424             }
425             try
426             {
427                 Lock();
428                 if (0 != m_MsgOrder.Count)
429                 {
430                     int mSlot = m_MsgOrder.Dequeue();
431                     ClientConnect curPlayer = m_ConnectPool[mSlot];
432                     ushort mOnePackLen = System.BitConverter.ToUInt16(curPlayer.m_AllData, curPlayer.m_AllDataHead);
433                     msg = new ClientMsgUnPack(curPlayer.m_AllData, curPlayer.m_AllDataHead, (ushort)mOnePackLen, curPlayer.m_UserID);
434                     curPlayer.m_AllDataHead += mOnePackLen;
435                 }
436             }
437             finally
438             {
439                 UnLock();
440             }
441         }
442 
443         public void SendTo(ref MsgPack msg, long userID)
444         {
445             try
446             {
447                 Lock();
448                 for(int i = 0 ; i < m_MaxClientConnect ; ++i)
449                 {
450                     ClientConnect curPlayer = m_ConnectPool[i];
451                     if (null != curPlayer.m_Connect && curPlayer.m_UserID == userID)
452                     {
453                         curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
454                         break;
455                     }
456                 }
457             }
458             finally
459             {
460                 UnLock();
461             }
462         }
463 
464         public void SendToAll(ref MsgPack msg)
465         {
466             try
467             {
468                 Lock();
469                 for (int i = 0; i < m_MaxClientConnect; ++i)
470                 {
471                     ClientConnect curPlayer = m_ConnectPool[i];
472                     if (null != curPlayer.m_Connect)
473                     {
474                         curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
475                         break;
476                     }
477                 }
478             }
479             finally
480             {
481                 UnLock();
482             }
483         }
484     }
485 }
SocketServer.cs
  1 using UnityEngine;
  2 using System.Collections;
  3 
  4 public class ClientMain : MonoBehaviour {
  5 
  6     // Use this for initialization
  7     ClientEventDispath m_Msg;
  8     SendBroadcast m_Sender;
  9     ReciveBroadcast m_Reciver;
 10     LanSocket.Client m_GameNet;
 11     string m_GameServerIP;
 12     bool m_bReady;
 13     float m_BroadTime;
 14 
 15     void Start () 
 16     {
 17         m_Sender = new SendBroadcast();
 18         m_Sender.Start(6666);
 19         m_Reciver = new ReciveBroadcast();
 20         m_Reciver.Start(6688);
 21 
 22         m_GameNet = new LanSocket.Client();
 23 
 24         m_GameServerIP = "";
 25 
 26         m_bReady = false;
 27         m_BroadTime = 0.0f;
 28 
 29         EventDispathBase.g_MaxEventNum = (int)NetMsgID.NET_MSG_END;
 30         m_Msg = new ClientEventDispath();
 31         m_Msg.RegistEvent((int)NetMsgID.S2C_SEND_ANIMAL_DATA, Action_S2C_SEND_ANIMAL_DATA);
 32     }
 33     
 34     void OnGUI()
 35     {
 36         if (GUILayout.Button("Record"))
 37         {
 38             MicroPhoneInput.getInstance().StartRecord();
 39         }
 40         if (GUILayout.Button("End"))
 41         {
 42             MicroPhoneInput.getInstance().StopRecord();
 43         }
 44         if (GUILayout.Button("send"))
 45         {
 46             byte[] data = MicroPhoneInput.getInstance().GetClipData();
 47 
 48             LanSocket.MsgPack audioBegin = new LanSocket.MsgPack();
 49             audioBegin.SetHead((int)NetMsgID.C2S_ASK_SEND_AUDIO_BEGIN);
 50             audioBegin.PackEnd();
 51             m_GameNet.Send(ref audioBegin);
 52 
 53             print("audio length = " + data.Length);
 54             int lastData = data.Length;
 55             int offset = 0;
 56             while (true)
 57             {
 58                 ushort sendNum = (ushort)lastData;
 59                 if (lastData > 3000)
 60                 {
 61                     sendNum = 3000;
 62                 }
 63                 LanSocket.MsgPack audioData = new LanSocket.MsgPack();
 64                 audioData.SetHead((int)NetMsgID.C2S_ASK_SEND_AUDIO);
 65                 audioData.Pack16bit(sendNum);
 66                 audioData.PackByte(data, offset, sendNum);
 67                 audioData.PackEnd();
 68                 m_GameNet.Send(ref audioData);
 69 
 70 //                 string result = string.Empty;
 71 //                 for (int i = 0; i < sendNum; i++)
 72 //                 {
 73 //                     result += System.Convert.ToString(data[offset + i], 16) + " ";
 74 //                 }
 75 //                 print(result);
 76 
 77                 offset += sendNum;
 78                 if (offset >= data.Length)
 79                 {
 80                     break;
 81                 }
 82                 lastData -= sendNum;
 83             }
 84             LanSocket.MsgPack audioEnd = new LanSocket.MsgPack();
 85             audioEnd.SetHead((int)NetMsgID.C2S_ASK_SEND_AUDIO_END);
 86             audioEnd.PackEnd();
 87             m_GameNet.Send(ref audioEnd);
 88 
 89 //             string result2 = string.Empty;
 90 //             for (int i = 0; i < data.Length; i++)
 91 //             {
 92 //                 result2 += System.Convert.ToString(data[i], 16) + " ";
 93 //             }
 94 //             print(result2);
 95         }
 96         if (GUILayout.Button("Play"))
 97         {
 98             MicroPhoneInput.getInstance().PlayRecord();
 99         }
100         if (GUILayout.Button("PlayByData"))
101         {
102             byte[] data = MicroPhoneInput.getInstance().GetClipData();
103             short[] decodeData = new short[data.Length / 2];
104             for (int i = 0; i < decodeData.Length; ++i)
105             {
106                 decodeData[i] = System.BitConverter.ToInt16(data, i * 2);
107             }
108             MicroPhoneInput.getInstance().PlayClipData(decodeData);
109         }
110     }
111     
112     // Update is called once per frame
113     void Update ()
114     {
115         if (m_bReady)
116         {
117             LanSocket.MsgUnPack msg = null;
118             m_GameNet.GetMsg(ref msg);
119             if (null != msg)
120             {
121                 print("here have one msg on client");
122             }
123 
124             if (Input.GetKeyUp(KeyCode.Space))
125             {
126                 LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();
127                 sendMsg.SetHead((int)NetMsgID.C2S_SELECT_ANIMAL);
128                 sendMsg.Pack16bit(1);
129                 sendMsg.PackEnd();
130                 m_GameNet.Send(ref sendMsg);
131                 print("send 1");
132             }
133         }
134         else
135         {
136             m_GameServerIP = m_Reciver.GetIP();
137             if ("".Equals(m_GameServerIP))
138             {
139                 m_BroadTime -= Time.deltaTime;
140                 if(m_BroadTime - Time.deltaTime < 0.0f)
141                 {
142                     m_BroadTime = 5.0f;
143                     m_Sender.Send();
144                 }
145             }
146             else
147             {
148                 print("get broadcast ip:" + m_GameServerIP);
149                 GameStart();
150             }
151         }
152     }
153     void OnDestroy()
154     {
155         m_GameNet.Destroy();
156         if(null != m_Reciver)
157         {
158             m_Reciver.Destroy();
159         }
160         if (null != m_Sender)
161         {
162             m_Sender.Destroy();
163         }
164     }
165 
166     void GameStart()
167     {
168         m_bReady = true;
169         m_GameNet.Start(m_GameServerIP, 8888);
170         try
171         {
172             m_Reciver.Destroy();
173             m_Sender.Destroy();
174         }
175         catch (System.Exception ex)
176         {
177             MonoBehaviour.print("GameStart catch:" + ex.Message);
178         }
179         m_Reciver = null;
180         m_Reciver = null;
181     }
182 
183     void Action_S2C_SEND_ANIMAL_DATA(LanSocket.MsgUnPack msg)
184     {
185     }
186 }
ClientMain.cs
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 enum NetMsgID
 5 {
 6     NET_MSG_START = 100,
 7     S2C_SEND_ANIMAL_DATA,
 8     C2S_SELECT_ANIMAL,
 9     C2S_ASK_SEND_AUDIO_BEGIN,
10     C2S_ASK_SEND_AUDIO,
11     C2S_ASK_SEND_AUDIO_END,
12 
13     NET_MSG_END,
14 }
Common.cs
  1 using UnityEngine;
  2 using System.Collections;
  3 
  4 public class ServerMain : MonoBehaviour 
  5 {
  6     bool m_Destroy;
  7     ServerEventDispath m_ClientMsg;
  8     ReciveBroadcast m_Reciver;
  9     SendBroadcast m_Sender;
 10     LanSocket.Server m_GameNet;
 11     byte[] m_AudioData;
 12     int m_AudioOffset;
 13     int m_AudioLen;
 14     void Start () 
 15     {
 16         m_Destroy = false;
 17         //广播
 18         m_Reciver = new ReciveBroadcast();
 19         m_Reciver.Start(6666);
 20         m_Sender = new SendBroadcast();
 21         m_Sender.Start(6688);
 22 
 23         //游戏网络
 24         m_GameNet = new LanSocket.Server();
 25         m_GameNet.Start(8888);
 26 
 27         m_AudioData = new byte[44100000];
 28         m_AudioOffset = 0;
 29         m_AudioLen = 0;
 30 
 31         m_ClientMsg = new ServerEventDispath();
 32         m_ClientMsg.RegistEvent((int)NetMsgID.C2S_ASK_SEND_AUDIO_BEGIN, Action_C2S_ASK_SEND_AUDIO_BEGIN);
 33         m_ClientMsg.RegistEvent((int)NetMsgID.C2S_ASK_SEND_AUDIO, Action_C2S_ASK_SEND_AUDIO);
 34         m_ClientMsg.RegistEvent((int)NetMsgID.C2S_ASK_SEND_AUDIO_END, Action_C2S_ASK_SEND_AUDIO_END);
 35     }
 36     
 37     // Update is called once per frame
 38     void Update () 
 39     {
 40         if(!m_Destroy)
 41         {
 42             LanSocket.ClientMsgUnPack clientMsg = null;
 43             m_GameNet.GetMsg(ref clientMsg);
 44             if (null != clientMsg)
 45             {
 46                 //print("Msg:" + clientMsg.GetMsgID() + " from: " + clientMsg.GetUserID());
 47 
 48                 EventNode mNode = new EventNode();
 49                 mNode.m_EventID = clientMsg.GetMsgID();
 50                 mNode.msg = clientMsg;
 51 
 52                 MonoBehaviour.print("Update EventID " + mNode.m_EventID + " ID: " + clientMsg.GetMsgID());
 53                 m_ClientMsg.AddEvent(mNode);
 54             }
 55 
 56             if(!"".Equals(m_Reciver.GetIP()))
 57             {
 58                 m_Sender.Send();
 59             }
 60 
 61             m_ClientMsg.Proccess();
 62         }
 63     }
 64 
 65     void OnDestroy()
 66     {
 67         m_Destroy = true;
 68         m_GameNet.Destroy();
 69         m_Reciver.Destroy();
 70         m_Sender.Destroy();
 71     }
 72 
 73     void Action_123(LanSocket.ClientMsgUnPack msg)
 74     {
 75         long userID = msg.GetUserID();
 76         ushort accountLen = msg.ReadUShort();
 77         string account = msg.ReadString(accountLen);
 78         ushort passLen = msg.ReadUShort();
 79         string pass = msg.ReadString(passLen);
 80 
 81         print("Action_123 account: " + account + " pass word: " + pass+" from user: " + userID);
 82 
 83         LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();
 84         sendMsg.SetHead(123);
 85         string strAccount = "test account";
 86         sendMsg.Pack16bit((ushort)strAccount.Length);
 87         sendMsg.PackString(strAccount, (ushort)strAccount.Length);
 88         string strPass = "test pass word";
 89         sendMsg.Pack16bit((ushort)strPass.Length);
 90         sendMsg.PackString(strPass, (ushort)strPass.Length);
 91         sendMsg.PackEnd();
 92         m_GameNet.SendTo(ref sendMsg, msg.GetUserID());
 93     }
 94 
 95     void Action_C2S_ASK_SEND_AUDIO_BEGIN(LanSocket.ClientMsgUnPack msg)
 96     {
 97         m_AudioOffset = 0;
 98         m_AudioLen = 0;
 99     }
100 
101     void Action_C2S_ASK_SEND_AUDIO(LanSocket.ClientMsgUnPack msg)
102     {
103         long userID = msg.GetUserID();
104         ushort dataLen = msg.ReadUShort();
105         byte[] audioData = msg.ReadByte(dataLen);
106 
107 //         string result = string.Empty;
108 //         for (int i = 0; i < dataLen; i++)
109 //         {
110 //             result += System.Convert.ToString(audioData[i], 16) + " ";
111 //         }
112 //         print(result);
113 
114         System.Buffer.BlockCopy(audioData, 0, m_AudioData, m_AudioOffset, (int)dataLen);
115         m_AudioOffset += dataLen;
116     }
117 
118     void Action_C2S_ASK_SEND_AUDIO_END(LanSocket.ClientMsgUnPack msg)
119     {
120         print("audio length: " + m_AudioOffset);
121         short[] decodeData = new short[m_AudioOffset / 2];
122         for (int i = 0; i < decodeData.Length; ++i)
123         {
124             decodeData[i] = System.BitConverter.ToInt16(m_AudioData, i * 2);
125         }
126         MicroPhoneInput.getInstance().PlayClipData(decodeData);
127 
128 //         string result = string.Empty;
129 //         for (int i = 0; i < m_AudioOffset; i++)
130 //         {
131 //             result += System.Convert.ToString(m_AudioData[i], 16) + " ";
132 //         }
133 //         print(result);
134     }
135 }
ServerMain.cs

以上为修改过的全部代码。

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