u3d局域网游戏网络(c# socket select 模型)——续
原文:http://www.cnblogs.com/saucerman/p/5555793.html
因为项目要加语音。语音数据都非常大。所以顺带就把之前写的网络模块一起测试了。
然后发现了一些bug,逐修。本来想在原文上面直接修改掉。但是恐怕已经看到的人拿去用了之后,再回头看也不一定能看明白,索性再写一文,将新文件直接放上来。
错误修改:
- 网络接收数据后,有一种情况没有处理完整,导致接收数据之后数据池的计数器没有向后偏移
- 网络数据处理后,当当前包仅剩1字节,下一个次数据进来的时候,需要2字节才能确认当前消息长度。增加了消息补齐机制。
- 增加了当网络数据拥堵的时候,直接断开当前链接。
- MsgUnPack的GetHead函数获取消息id的时候使用了错误的函数,导致数据偏移不正确
- MsgUnPack的UnPack(byte[] mBuff, ushort offset, ushort len),由于总buff扩大,导致offset参数超过上限,改为int
- 消息事件增加了错误消息ID过滤
由于语音的需求,将原本的服务器段接受buff容量扩大一倍。增加了语音模块。
特别说下语音模块。
http://blog.csdn.net/huutu/article/details/20216613
这是原文。
稍做修改。特别说一下这个语音模块在使用中容易遇到的问题。
- 如果声音太小,可能是你录音设备的侦听开得不够。
- 本地测试还好,放到网络上之后,因为代码里有处理,如果没有对象会创建对象并且添加必要组件。原文在创建的时候比特率是手动填写的。导致我客户端一个比特率,服务器一个比特率。然后客户端听着一切正常,传给服务器就错了。后来查了一天,排查各个代码段之后才找到这个原因。
以下是代码:
新增语音模块:
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 }
接下来的都和之前的一样。
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
以上为修改过的全部代码。