• 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

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

  • 相关阅读:
    search
    longestValidParentheses
    nextPermutation
    linux下通过安装xampp搭建环境卸载xampp、以及网站搬家-64位系统Apache启动不了的问题
    对拍器 ADC-ACMDataCreater
    Educational Codeforces Round 86 (Rated for Div. 2) A~D
    Codeforces Round #637 (Div. 2) A~D
    Codeforces Round #636 (Div. 3) A~D
    Codeforces Round #635 (Div. 2) A~D
    原型设计工具比较及实践 基于WolframAlphaAPI的科学计算器原型设计
  • 原文地址:https://www.cnblogs.com/saucerman/p/5566545.html
Copyright © 2020-2023  润新知