首页 > 编程语言 > 详细

Unity3D_在项目中网络通信脚本的处理

时间:2021-01-22 11:53:19      阅读:31      评论:0      收藏:0      [点我收藏+]

记录下之前开发SLG时,处理的网络通信相关的逻辑

ByteArray类

using UnityEngine;
using System;

namespace IO
{
    public class ByteArray
    {
        protected byte[] m_buffer = null;
        protected int readOffset = 0;
        protected int writeOffset = 0;

        public int GetDataLength()
        {
            return writeOffset - readOffset;
        }

        public int GetHeadOffset()
        {
            return readOffset;
        }

        public void SetHeadOffset(int offset)
        {
            readOffset = offset;
        }

        public byte[] readBytes(int nLen)
        {
            if (readOffset + nLen > this.m_buffer.Length)
            {
                Debug.Log(" Failed: 长度越界  NetReader: getBYTE ");
                 throw new IndexOutOfRangeException(" Failed: 长度越界  NetReader: getBYTE ");
            }
            byte[] buf = new byte[nLen];
            Buffer.BlockCopy(m_buffer, readOffset, buf, 0, nLen);
            this.readOffset += nLen;
            return buf;
        }

        public int INCREAT_SIZE = 100;

        void cleanReadOffset()
        {
            Buffer.BlockCopy(m_buffer,readOffset,m_buffer,0,writeOffset - readOffset);
            readOffset = 0;
            writeOffset -= readOffset;
        }

        void requestBufferSize(int expectLength)
        {
            if (m_buffer == null)
            {
                m_buffer = new byte[0];
                readOffset = 0;
                writeOffset = 0;
            }

            int remainSize = m_buffer.Length - writeOffset;

            if (remainSize < expectLength)
            {
                if(remainSize + readOffset >= expectLength)
                {
                    cleanReadOffset();
                    return;
                }

                int newSize = Mathf.CeilToInt((expectLength + GetDataLength()) / (float)INCREAT_SIZE) * INCREAT_SIZE;

                byte[] buf = new byte[newSize];

                Buffer.BlockCopy(m_buffer,readOffset, buf, 0,writeOffset - readOffset);

                m_buffer = buf;
                readOffset = 0;
                writeOffset -= readOffset;
            }
        }

        public void writeBytes(byte[] buffer)
        {
            if (buffer.Length < 1)
            {
                return;
            }

            requestBufferSize(buffer.Length);

            Buffer.BlockCopy(buffer, 0, m_buffer, writeOffset, buffer.Length);

            writeOffset += buffer.Length;
        }

        public int dataSize()
        {
            if (m_buffer == null)
            {
                return 0;
            }
            return m_buffer.Length - readOffset;
        }

        public int dataPtr()
        {
            return readOffset;
        }

        public string dataString()
        {
            return "";
        }

        public void consumeByte(int len)
        {
            System.Diagnostics.Debug.Assert(m_buffer.Length >= readOffset + len);
            readOffset += len;
        }

        public void clearBuffer()
        {
            m_buffer = new byte[0];

            readOffset = 0;
        }

        sbyte byteAtIndex(int index)
        {
            if (index > m_buffer.Length)
            {
                return 0;
            }

            return Convert.ToSByte(m_buffer[index]);
        }

        public sbyte readSbyte()
        {
            int nLen = sizeof(byte);
            if (this.readOffset + nLen > this.m_buffer.Length)
            {
                Debug.Log(" Failed: 长度越界  NetReader: readInt8 ");
                throw new IndexOutOfRangeException(" Failed: 长度越界  NetReader: readInt8 ");
            }
            byte bt = m_buffer[readOffset];
            this.readOffset += nLen;
            sbyte sb;
            unchecked
            {
                sb = (sbyte)bt;
            }
            return sb;
        }

        public byte readInt8()
        {
            int nLen = sizeof(byte);
            if (this.readOffset + nLen > this.m_buffer.Length)
            {
                Debug.Log(" Failed: 长度越界  NetReader: readInt8 ");
                throw new IndexOutOfRangeException(" Failed: 长度越界  NetReader: readInt8 ");
            }
            byte bt = m_buffer[readOffset];
            this.readOffset += nLen;
            return bt;
        }
        public short readInt16()
        {
            int nLen = sizeof(short);
            if (this.readOffset + nLen > this.m_buffer.Length)
            {
                Debug.Log(" Failed: 长度越界  NetReader: readInt16 ");
                throw new IndexOutOfRangeException(" Failed: 长度越界  NetReader: readInt16 ");
            }
            short val = BitConverter.ToInt16(m_buffer, readOffset);
            readOffset += nLen;
            return val;

        }
        public int readInt32()
        {
            int nLen = sizeof(int);
            if (this.readOffset + nLen > this.m_buffer.Length)
            {
                Debug.Log(" Failed: 长度越界  NetReader: readInt32 ");
                throw new IndexOutOfRangeException(" Failed: 长度越界  NetReader: readInt32 ");
            }
            int val = BitConverter.ToInt32(m_buffer, readOffset);
            readOffset += nLen;
            return val;
        }

        public long readInt64()
        {
            int nLen = sizeof(Int64);
            if (this.readOffset + nLen > this.m_buffer.Length)
            {
                Debug.Log(" Failed: 长度越界  NetReader: readInt64 ");
                throw new IndexOutOfRangeException(" Failed: 长度越界  NetReader: readInt64 ");
            }
            long val = BitConverter.ToInt64(m_buffer, readOffset);
            readOffset += nLen;
            return val;
        }

        public void writeInt8(byte value)
        {
            byte[] val = new byte[1];
            val[0] = value;
            writeBytes(val);
        }

        public void writeInt16(short value)
        {
            byte[] val = BitConverter.GetBytes(value);
            writeBytes(val);
        }

        public void writeInt32(int value)
        {
            byte[] val = BitConverter.GetBytes(value);
            writeBytes(val);
        }

        public void writeInt64(long value)
        {
            byte[] val = BitConverter.GetBytes(value);
            writeBytes(val);
        }

        public void writeByteBuffer(ByteArray buffer)
        {
            writeBytes(buffer.m_buffer);
        }

        public ByteArray copyBufferPart(int startIndex, int nCount)
        {
            ByteArray buffer = new ByteArray();

            byte[] ByteArray = new byte[nCount];

            Buffer.BlockCopy(m_buffer, startIndex, ByteArray, 0, nCount);

            buffer.writeBytes(ByteArray);

            return buffer;

        }

        public ByteArray copyBufferAll()
        {
            ByteArray buffer = new ByteArray();

            int byteLen = dataSize() - dataPtr();

            byte[] ByteArray = new byte[byteLen];

            Buffer.BlockCopy(m_buffer, readOffset, ByteArray, 0, byteLen);

            buffer.writeBytes(ByteArray);

            return buffer;
        }

        //void cleanHeadOffset();
        public byte[] getBuffer()
        {
            if (m_buffer !=null)
            {
                return m_buffer;
            }
            return new byte[0];
        }

    }
}

ByteArrayQueue类

using System;
using System.Collections;

namespace IO
{
    public class ByteArrayQueue
    {
        protected ArrayList m_queue;

        public ByteArrayQueue()
        {
            m_queue = new ArrayList();
        }

        public void pushBack(ByteArray buffer)
        {
            m_queue.Add(buffer);
        }

        public void pushFront(ByteArray buffer)
        {
            m_queue.Insert(0, buffer);
        }

        public void popBack()
        {
            m_queue.RemoveAt(m_queue.Count);
        }
        public void popFront()
        {
            m_queue.RemoveAt(0);
        }
        //public void popBackAndDelete();
        //public void popFrontAndDelete();

        public void removeAll()
        {
            m_queue.Clear();
        }
        public void deleteAll()
        {
            m_queue.Clear();
        }

        public ByteArray front()
        {
            return (ByteArray)m_queue[0];
        }
        public ByteArray back()
        {
            return (ByteArray)m_queue[m_queue.Count];
        }
        public ByteArray frontAndPop()
        {
            if (m_queue.Count < 1)
            {
                return null;
            }
            ByteArray buf = (ByteArray)m_queue[0];
            m_queue.RemoveAt(0);
            return buf;
        }
        public ByteArray backAndPop()
        {
            if (m_queue.Count < 1)
            {
                return null;
            }
            ByteArray buf = (ByteArray)m_queue[m_queue.Count];
            m_queue.RemoveAt(m_queue.Count);
            return buf;
        }

        //public void lockQueue();
        //public void unlockQueue();

        public bool empty()
        {
            return m_queue.Count == 0;

        }
        
        public int Count()
        {
            return m_queue.Count;
        }
    }
}

ByteStream类

using System;
using System.Collections;

namespace IO
{
    public class ByteStream
    {
        protected ByteArray m_pBuffer;

        public byte readInt8()
        {
            return m_pBuffer.readInt8();
        }

        public void writeInt8(byte value)
        {
            m_pBuffer.writeInt8(value);
        }

        public Int16 readInt16()
        {
            return m_pBuffer.readInt16();
        }

        public void writeInt16(short value)
        {
            m_pBuffer.writeInt16(value);
        }

        public Int32 readInt32()
        {
            return m_pBuffer.readInt32();
        }

        public void writeInt32(int value)
        {
            m_pBuffer.writeInt32(value);
        }

        public Int64 readInt64()
        {
            return m_pBuffer.readInt64();
        }

        public void writeInt64(Int64 value)
        {
            m_pBuffer.writeInt64(value);
        }

        public string readString()
        {
            Int16 nStrLen = 0;

            nStrLen = readInt16();

            System.Diagnostics.Debug.Assert(m_pBuffer.dataSize() >= nStrLen);

            byte[] b = m_pBuffer.readBytes(nStrLen);

            string s = System.Text.Encoding.UTF8.GetString(b);
            return s;
        }

        public void writeString(string s)
        {
            short len = (short)s.Length;
            writeInt16(len);
            byte[] val = System.Text.Encoding.UTF8.GetBytes(s);
            m_pBuffer.writeBytes(val);
        }

        public ByteArray byteBuffer()
        {
            return m_pBuffer;
        }

        public void attachBuffer(ByteArray pBuffer)
        {
            if (m_pBuffer != null)
            {
                detachBuffer();
            }

            m_pBuffer = pBuffer;
        }

        public void detachBuffer()
        {
            m_pBuffer = null;
        }

    }
}

Endian类

using System;

namespace IO
{
    //大小端转换
    public static class Endian
    {
        public static short SwapInt16(this short n)
        {
            return (short)(((n & 0xff) << 8) | ((n >> 8) & 0xff));
        }

        public static ushort SwapUInt16(this ushort n)
        {
            return (ushort)(((n & 0xff) << 8) | ((n >> 8) & 0xff));
        }

        public static int SwapInt32(this int n)
        {
            return (int)(((SwapInt16((short)n) & 0xffff) << 0x10) |
                          (SwapInt16((short)(n >> 0x10)) & 0xffff));
        }

        public static uint SwapUInt32(this uint n)
        {
            return (uint)(((SwapUInt16((ushort)n) & 0xffff) << 0x10) |
                           (SwapUInt16((ushort)(n >> 0x10)) & 0xffff));
        }

        public static long SwapInt64(this long n)
        {
            return (long)(((SwapInt32((int)n) & 0xffffffffL) << 0x20) |
                           (SwapInt32((int)(n >> 0x20)) & 0xffffffffL));
        }

        public static ulong SwapUInt64(this ulong n)
        {
            return (ulong)(((SwapUInt32((uint)n) & 0xffffffffL) << 0x20) |
                            (SwapUInt32((uint)(n >> 0x20)) & 0xffffffffL));
        }
    }
}

Net类

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
using IO;
using UnityEditor;

enum KickCode
{
    /** 0 - 重复登录 */
    eDUPLICATE_LOGIN = 0,
    /** 1 - 玩家被封禁 */
    eBLOCK_LOGIN,
    /** 2 - 登录超时 */
    eLOGIN_TIMEOUT,
};

enum NetErrorType
{
    eSendError = 0,     /*发送数据错误    -(重激活)*/
    eRecvError = 1,            /*接受数据错误    -(重激活)*/
};

enum NetStatue
{
    /** 0 - 未连接 */
    eDISCONNECT = 0,
    /** 1 - 正常工作中 */
    eWORKING,
    /** 2 - 事务行错误 */
    eTRANSERROR,
};


namespace NetCore
{
    public class Net : MonoBehaviour
    {
        AutoResetEvent threadExitEvent = new AutoResetEvent(false);
        bool threadExit = true;

        /*套接字*/
        private Socket _socket = null;
        /*异步线程*/
        private Thread _thread = null;
        /**/
        private const int TimeOut = 30;//30秒的超时时间
        /*端口*/
        private int _port;
        /*IP*/
        private string _ip;

        public bool stopReceive = false;
        public bool stopSend = false;
        public bool sendFailed = false;

        private Mutex flagWorkingMutex = new Mutex();
        private bool bWorking = false;

        private LinkedList<Action> threadTaskQueue = new LinkedList<Action>();
        private LinkedList<Action> taskQueue = new LinkedList<Action>();

        /*发送队列*/
        private ByteArrayQueue _sendQueue;
        /*接受队列*/
        private ByteArrayQueue _receiveQueue;
        //错误队列
        private List<int> _errorQueue;
        //最大尝试次数
        private int mostRetryTimes = 3;

        Action<int> fnErrorNotify = null;

        //网络状态
        private NetStatue statue = NetStatue.eDISCONNECT;

        /// 检测移动设备的网络环境
        public bool CheckInternetReachable()
        {
            /*该状态只能检测WIFI和运营商网络,热点可能无法被检测到*/
            UnityEngine.NetworkReachability state = UnityEngine.Application.internetReachability;

            if (state == NetworkReachability.NotReachable)
                return false;

            return true;
        }

        /// 获取网络状态类型
        /// <returns>0 网络未连接 1 运营商网络 2 Wifi </returns>
        public int GetDeviceInterntState()
        {
            UnityEngine.NetworkReachability state = UnityEngine.Application.internetReachability;
            return (int)state;
        }

        public void Awake()
        {
            _sendQueue      = new ByteArrayQueue();
            _receiveQueue   = new ByteArrayQueue();
            _errorQueue     = new List<int>();

            //StartNet();
        }

//         void OnGUI()
//         {
//             if (GUI.Button(new Rect(1000, 0, 200, 50), "断线"))
//             {
//                 _pushTask(() =>
//                 {
//                     closeConnect();
// 
//                     onNetRecvError();
//                 });
//             }
// 
// 
//         }

        private void _pushThreadTask(Action fn)
        {
            lock (threadTaskQueue)
            {
                threadTaskQueue.AddFirst(fn);
            }
        }

        private void _pushTask(Action fn)
        {
            lock (taskQueue)
            {
                taskQueue.AddFirst(fn);
            }
        }

        private void _handleThreadTask()
        {
            lock (threadTaskQueue)
            {
                while (threadTaskQueue.Count > 0)
                {
                    Action act = threadTaskQueue.First.Value;
                    threadTaskQueue.RemoveFirst();
                    act();
                }
            }
        }

        private void _handeTask()
        {
            lock (taskQueue)
            {
                while (taskQueue.Count > 0)
                {
                    Action act = taskQueue.First.Value;
                    taskQueue.RemoveFirst();
                    act();
                }
            }
        }

        public void Update()
        {
            _handeTask();
        }

        /// 设置IP和端口
        public void SetIp(string ip, int port)
        {
            _ip = ip;
            _port = port;
        }

        /// 初始化网络
        public void startNet()
        {
            Debug.Assert(_socket == null);
            Debug.Assert(_thread == null);

            if (_socket != null || _thread != null)
                return;

            stopReceive = false;
            stopSend = false;

            _thread = new Thread(new ThreadStart(_threadEntry));
            _thread.Start();

            return;
        }

        /// <summary>
        /// 网络正在连接中
        /// </summary>
        /// <returns></returns>
        public bool isConnected()
        {
            if (_socket == null)
                return false;

            return _socket.Connected;
        }

        public bool isWorking()
        {
            return bWorking;
        }

        public void offWorking()
        {
            lock (flagWorkingMutex)
            {
                bWorking = false;
            }
        }

        public void working()
        {
            lock (flagWorkingMutex)
            {
                bWorking = true;
            }
        }

        public void ClearPacketQueue()
        {
            lock (_sendQueue)
            {
                _sendQueue.removeAll();
            }
        }

        public void connectNetAsyc(Action<bool> cb)
        {
            if (_socket!=null)
                return;

            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            ClearPacketQueue();

            lock (threadTaskQueue)
            {
                _pushThreadTask(() =>
                {
                    IAsyncResult rst = null;
                    try {
                        rst = _socket.BeginConnect(_ip, _port, null, null);
                        rst.AsyncWaitHandle.WaitOne(2000, true);
                    }
                    catch (Exception ex)
                    {
                        Debug.Log(ex.ToString());

                        _pushTask(() =>
                        {
                            cb(false);
                        });
                    }

                    bool success = false;

                    if (rst.IsCompleted  && _socket.Connected)
                    {
                        success = true;
                        _socket.EndConnect(rst);
                        Debug.Log("网络连接成功");
                    }
                    else
                    {
                        success = false;

                        _closeSocket();
                        Debug.Log("网络连接失败");
                    }

                    

                    if (cb != null)
                        _pushTask(() =>
                        {
                            cb(success);
                        });
                });
            }
        }

        /// <summary>
        /// 压入发送数据
        /// </summary>
        /// <param name="buffer"></param>
        public void sendBytes(ByteArray buffer)
        {
            if (sendFailed)
            {
                sendFailed = false;

                _pushTask(() =>
                {
                    closeConnect();
                    onNetSendError();
                });

                return;
            }

            lock (_sendQueue)
            {
                _sendQueue.pushBack(buffer);
            }
        }

        /// <summary>
        /// 获取第一条接受的数据
        /// </summary>
        public ByteArray pickRevQueue()
        {
            ByteArray byteBuffer = null;
            lock (_receiveQueue)
            {
                byteBuffer = _receiveQueue.frontAndPop();
            }

            return byteBuffer;
        }

        //拾取错误
        public int pickErrorQueue()
        {
            int error = -1;
            lock (_errorQueue)
            {
                if (_errorQueue.Count > 0)
                {
                    error = _errorQueue[0];
                    _errorQueue.RemoveAt(0);
                }
            }

            return error;
        }

        public void clearDataQueue()
        {
            _sendQueue.removeAll();
            _receiveQueue.removeAll();
        }

        private void _closeSocket()
        {
            if (_socket == null)
                return;

            _socket.Close();
            _socket = null;

            offWorking();
        }

        /// <summary>
        /// 断开链接
        /// </summary>
        public void closeConnect()
        {
            if (!isConnected())
                return;

            _pushThreadTask(() =>
            {
                _closeSocket();

                threadExitEvent.Set();
            });

            threadExitEvent.WaitOne();
        }

        public void shutdownThread()
        {
            if (_thread == null)
                return;

            _pushThreadTask(() =>
            {
                threadExit = false;
            });

            _thread.Join();

            _thread = null;
        }

        /// <summary>
        /// 断开链接
        /// </summary>
        public void shutdownNet()
        {
            if (_thread == null)
                return;

            closeConnect();
            shutdownThread();
            clearDataQueue();
        }

        /// <summary>
        /// 线程
        /// </summary>
        private void _threadEntry()
        {
            while (threadExit)
            {
                if (_socket != null)
                {
                    _sendData();

                    _recvData();
                }

                _handleThreadTask();

                Thread.Sleep(50);
            }

            threadExit = true;
        }


        /// <summary>
        /// 发送数据
        /// </summary>
        private bool _sendData()
        {
            if (!isConnected() || !isWorking() || stopSend)
                return false;

            ByteArray buffer;
            lock (_sendQueue)
            {
                if (_sendQueue.empty()) return false;
                buffer = _sendQueue.front();
            }

            byte[] data = buffer.getBuffer();

            try
            {
                int len = buffer.GetDataLength();

                if (len < 8)
                {
                    Debug.Log("发送数据长度小于8");
                }

                IAsyncResult asyncSend = _socket.BeginSend(data, 0, buffer.GetDataLength(), SocketFlags.None, null, null);
                bool bSuccess = asyncSend.AsyncWaitHandle.WaitOne(5000, true);
                if (!bSuccess)
                {

                    Debug.Log("发送数据失败");

                    _closeSocket();

                    _pushTask(() =>
                    {
                        onNetSendError();
                    });
                }
                else
                {
                    lock (_sendQueue)
                    {
                        _sendQueue.popFront();
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Debug.Log("发送数据失败,请检查网络连接 :" + ex.ToString());

                _closeSocket();

                offWorking();

                _pushTask(() =>
                {
                    onNetSendError();
                });
            }

            return false;
        }

        private void _recvError()
        {
            _closeSocket();

            _pushTask(() =>
            {
                onNetRecvError();
            });

            offWorking();
        }

        /// <summary>
        /// 异步接受数据
        /// </summary>
        private void _recvData()
        {
            if (!isConnected() || !isWorking() || stopReceive)
                return;

            try
            {
                if (_socket.Poll(5, SelectMode.SelectRead))
                {
                    byte[] prefix = new byte[4]; //包长度

                    int recnum = 0;

                    recnum = _socket.Receive(prefix);

                    if (recnum == 4)
                    {
                        int len = BitConverter.ToInt32(prefix, 0);
                        int datalen = Endian.SwapInt32(len) - 4;
                        byte[] data = new byte[datalen];
                        int startIndex = 0;
                        recnum = 0;

                        do
                        {
                            int rev = _socket.Receive(data, startIndex, datalen - recnum, SocketFlags.None);
                            recnum += rev;
                            startIndex += rev;
                        } while (recnum != datalen);

                        ByteArray buffer = new ByteArray();
                        buffer.writeBytes(data);

                        lock (_receiveQueue)
                        {
                            _receiveQueue.pushBack(buffer);
                        }
                    }
                    else if (recnum == 0)
                    {
                        Debug.Log("网络接收到0字节(断开).");
                        _recvError();
                    }
                }
                else if (_socket.Poll(5, SelectMode.SelectError))
                {
                    Debug.Log("SelectError Socket 状态错误");
                    _recvError();
                }
            }
            catch (Exception ex)
            {
                Debug.Log("接收网络数据异常:" + ex.ToString());

                _recvError();
            }
        }

        /// <summary>
        /// 接受队列是否为空
        /// </summary>
        public bool isRecvQueueEmpty()
        {
            bool rst = false;
            rst = _receiveQueue.empty();
            return rst;
        }

        private void onNetRecvError()
        {
            notifyError(NetErrorType.eRecvError);
        }

        private void onNetSendError()
        {
            notifyError(NetErrorType.eSendError);
        }

        private void notifyError(NetErrorType err)
        {
            if (fnErrorNotify != null)
            {
                fnErrorNotify((int)err);
            }
        }

        public void setErrorNotify(Action<int> lfn)
        {
            fnErrorNotify = lfn;
        }
    }
    
}

PackProtocol类

using System;
using System.Collections.Generic;
using IO;

namespace NetCore
{
    public class PackProtocol
    {
        public short m_sn = 0;

        public ByteArray signByteStream(byte module, byte method, byte[] data)
        {
            //* <p>[4字节] 长度
            //* <p>[1字节] 校验码
            //* <p>[1字节] 循环顺序号(从0开始,每次请求+1,不符合则断开; 0,1,2,...,127,-128,-127,...,-1,0,1,...)
            //* <p>[1字节] 模块号
            //* <p>[1字节] 命令号
            //包头长度 8 字节
            int len = data.Length + 8;
            short validateCode = fnvhash(m_sn, module, method, len);

            ByteArray byteBuffer = new ByteArray();
            byteBuffer.writeInt32(Endian.SwapInt32(len));
            byteBuffer.writeInt8((byte)validateCode);
            byteBuffer.writeInt8((byte)m_sn);
            byteBuffer.writeInt8(module);
            byteBuffer.writeInt8(method);
            byteBuffer.writeBytes(data);

            m_sn++;

            return byteBuffer;
        }

        public ByteArray signByteStream(ByteArray byteBuffer)
        {
            //* <p>[4字节] 长度
            //* <p>[1字节] 校验码
            //* <p>[1字节] 循环顺序号(从0开始,每次请求+1,不符合则断开; 0,1,2,...,127,-128,-127,...,-1,0,1,...)
            //* <p>[1字节] 模块号
            //* <p>[1字节] 命令号
            //包头长度 8 字节
            //self.netSendPackVStream:writeInt8(packet.req[‘_MOD_‘])
            //self.netSendPackVStream:writeInt8(packet.req[‘_MED_‘])
            //self.netSendPackVStream:writeInt32(0)--预留六字节
            //self.netSendPackVStream:writeInt16(0)
            //byte[] data = byteBuffer.getBuffer();
            int len = byteBuffer.GetDataLength();
            byte module = byteBuffer.readInt8();
            byte method = byteBuffer.readInt8();
            short validateCode = fnvhash(m_sn, module, method, len);

            ByteArray buf = new ByteArray();
            buf.writeInt32(Endian.SwapInt32(len));
            buf.writeInt8((byte)validateCode);
            buf.writeInt8((byte)m_sn);
            buf.writeInt8(module);
            buf.writeInt8(method);

            byte[] src = buf.getBuffer();
            byte[] dec = byteBuffer.getBuffer();

            Buffer.BlockCopy(src, 0, dec, 0, buf.GetDataLength());
            byteBuffer.SetHeadOffset(0);

            m_sn++;

            return buf;
        }

        public void resetSN()
        {
            m_sn = 0;
        }

        private short fnvhash(short sn, short module, short cmd, Int32 len)
        {
            int hash = 117;
            int prime = 101;
            int lenLow = len & 0xFFFF;
            int lenHight = (int)(len & 0xFFFF0000) >> 16;
            hash = (hash ^ sn) * prime;
            hash = (hash ^ module) * prime;
            hash = (hash ^ cmd) * prime;
            hash = (hash ^ lenLow) * prime;
            hash = (hash ^ lenHight) * prime;
            return (short)(hash & 0xFF);
        }
    }
}

VarintStream类

using System;
using System.Collections;

namespace IO
{
    public class VarintStream : ByteStream
    {
        public sbyte readVarint8()
        {
            return (sbyte)readVarint32ByteToSbyte();
        }

        public void writeVarint8(byte value)
        {
            writeVarint32Byte(value);
        }

        public Int16 readVarint16()
        {
            return (Int16)readVarint32Byte();
        }

        public void writeVarint16(Int16 value)
        {
            writeVarint32Byte((UInt16)value);
        }

        public Int32 readVarint32()
        {
            return (Int32)readVarint32Byte();
        }

        public void writeVarint32(Int32 value)
        {
            writeVarint32Byte((UInt32)value);
        }

        public Int64 readVarint64()
        {
            return (Int64)readVarint64Byte();
        }
        public void writeVarint64(Int64 value)
        {
            writeVarint64Byte((UInt64)value);
        }

        protected void writeVarint32Byte(UInt32 value)
        {
            if (value < 128)
            {
                writeInt8((byte)value);
                return;
            }

            while (value > 127)
            {
                writeInt8((byte)((value & 0x7F) | 0x80));
                value >>= 7;
            }
            writeInt8((byte)value);
        }

        protected uint readVarint32Byte()
        {
            int tmp = m_pBuffer.readInt8();
            if (tmp < 128)
            {
                return (uint)tmp;
            }

            int result = tmp & 0x7f;
            if ((tmp = m_pBuffer.readInt8()) < 128)
            {
                result |= tmp << 7;
            }
            else
            {
                result |= (tmp & 0x7f) << 7;
                if ((tmp = m_pBuffer.readInt8()) < 128)
                {
                    result |= tmp << 14;
                }
                else
                {
                    result |= (tmp & 0x7f) << 14;
                    if ((tmp = m_pBuffer.readInt8()) < 128)
                    {
                        result |= tmp << 21;
                    }
                    else
                    {
                        result |= (tmp & 0x7f) << 21;
                        result |= (tmp = m_pBuffer.readInt8()) << 28;
                        if (tmp >= 128)
                        {
                            for (int i = 0; i < 5; i++)
                            {
                                if (m_pBuffer.readInt8() < 128)
                                {
                                    return (uint)result;
                                }
                            }
                            throw new InvalidCastException();
                        }
                    }
                }
            }
            return (uint)result;
        }

        protected uint readVarint32ByteToSbyte()
        {
            byte b = m_pBuffer.readInt8();
            sbyte sb;
            unchecked
            {
                sb = (sbyte)b;
            }
            int tmp = sb;
            if (tmp < 128)
            {
                return (uint)tmp;
            }

            int result = tmp & 0x7f;
            if ((tmp = m_pBuffer.readInt8()) < 128)
            {
                result |= tmp << 7;
            }
            else
            {
                result |= (tmp & 0x7f) << 7;
                if ((tmp = m_pBuffer.readInt8()) < 128)
                {
                    result |= tmp << 14;
                }
                else
                {
                    result |= (tmp & 0x7f) << 14;
                    if ((tmp = m_pBuffer.readInt8()) < 128)
                    {
                        result |= tmp << 21;
                    }
                    else
                    {
                        result |= (tmp & 0x7f) << 21;
                        result |= (tmp = m_pBuffer.readInt8()) << 28;
                        if (tmp >= 128)
                        {
                            for (int i = 0; i < 5; i++)
                            {
                                if (m_pBuffer.readInt8() < 128)
                                {
                                    return (uint)result;
                                }
                            }
                            throw new InvalidCastException();
                        }
                    }
                }
            }
            return (uint)result;
        }

        protected void writeVarint64Byte(UInt64 value)
        {
            while (value > 127)
            {
                writeInt8((byte) ((value & 0x7F) | 0x80));
                value >>= 7;
            }
            while (value > 127)
            {
                writeInt8((byte)((value & 0x7F) | 0x80));
                value >>= 7;
            }
            writeInt8((byte)value);
        }

        protected ulong readVarint64Byte()
        {
            int shift = 0;
            ulong result = 0;
            while (shift < 64)
            {
                byte b = m_pBuffer.readInt8();
                result |= (ulong)(b & 0x7F) << shift;
                if ((b & 0x80) == 0)
                {
                    return result;
                }
                shift += 7;
            }
            throw new InvalidCastException();
        }

        public string readVarintString()
        {
            Int16 nStrLen = 0;

            nStrLen = readVarint16();

            byte[] b = m_pBuffer.readBytes(nStrLen);

            string s = System.Text.Encoding.UTF8.GetString(b);

            return s;
        }

        public void writeVarintString(string s)
        {
            byte[] val = System.Text.Encoding.UTF8.GetBytes(s);
            short len = (short)val.Length;
            writeVarint16(len);
            m_pBuffer.writeBytes(val);
        }
    }
}

WebDownloader类

using System;
using System.Collections.Generic;
using System.Collections;
using UnityEngine;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Net;

public class DownFileInfo
{
    public string url;
    public string filePath;
    public string md5;
}

public class ProgressInfo
{

}


public class WebDownloader
{
    public float progrsss;
    private Stopwatch sw = new Stopwatch();

    //线程
    private Thread thread;
    //需要下载
    private Queue<DownFileInfo> _downQueue = new Queue<DownFileInfo>();

    //正在下载的文件信息
    private Dictionary<string,string> _downloading = new Dictionary<string,string>();

    public void StartDwonload()
    {
        thread = new Thread(delegate()
        {
            while (true)
            {
                _Download();
            }
        });
        thread.Start();
    }

    private void _Download()
    {
        lock (_downQueue)
        {
            if (_downQueue.Count > 0)
            {
                DownFileInfo fileInfo = _downQueue.Dequeue();
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        sw.Start();
                        client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                        client.DownloadFileAsync(new System.Uri(fileInfo.url), fileInfo.filePath);
                    }
                }
                catch (Exception ex)
                {
                    UnityEngine.Debug.LogError(ex.Message);
                }
            }
        }
    }

    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        string value = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
        UnityEngine.Debug.Log(value);
        if (e.ProgressPercentage == 100 && e.BytesReceived == e.TotalBytesToReceive)
        {
            sw.Reset();
        }
    }

    public void AddDwonloadTask(string url,string filePath,string md5)
    {
        DownFileInfo fileInfo = new DownFileInfo();
        fileInfo.url = url;
        fileInfo.filePath = filePath;
        fileInfo.md5 = md5;
        lock (_downQueue)
        {
            _downQueue.Enqueue(fileInfo);
        }
    }

    public void CheckMd5()
    {

    }
    
}

 

Unity3D_在项目中网络通信脚本的处理

原文:https://www.cnblogs.com/makeamericagreatagain/p/14312060.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!