| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Net; |
| | | using System.Net.Sockets; |
| | | using System.Threading; |
| | | |
| | | public class ClientSocketController |
| | | { |
| | | Socket m_Socket; |
| | | public Socket socket { |
| | | get { return m_Socket; } |
| | | } |
| | | |
| | | private int connectWaitTime = 2000; // 10秒 |
| | | private Thread m_packageThread; |
| | | private byte[] bufferBytes = new byte[4096]; // 4K,单包字节数组缓存 |
| | | private byte[] fragmentBytes; //留包后的内容 |
| | | private long getBytesTotal = 0; //发送的数据总量 |
| | | private long sendBytesTotal = 0; //发送的数据总量 |
| | | |
| | | public bool Connected { get { return m_Socket == null ? false : m_Socket.Connected; } } |
| | | |
| | | public bool isStopTreading { get; private set; } |
| | | |
| | | string ip; |
| | | int port; |
| | | Action onConnected = null; |
| | | |
| | | public ClientSocketController() |
| | | { |
| | | } |
| | | |
| | | public void Connect(string _ip, int _port, Action _onConnected) |
| | | { |
| | | try |
| | | { |
| | | ip = _ip; |
| | | port = _port; |
| | | onConnected = _onConnected; |
| | | Dns.BeginGetHostAddresses(_ip, OnGetHostAddresses, null); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | DesignDebug.LogError(e.Message); |
| | | } |
| | | } |
| | | |
| | | private void OnGetHostAddresses(IAsyncResult _result) |
| | | { |
| | | var ipAddresses = Dns.EndGetHostAddresses(_result); |
| | | |
| | | if (ipAddresses[0].AddressFamily == AddressFamily.InterNetworkV6) |
| | | { |
| | | DesignDebug.Log("当前使用的网络: IPV6"); |
| | | m_Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); |
| | | } |
| | | else |
| | | { |
| | | DesignDebug.Log("当前使用的网络: IPV4"); |
| | | m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
| | | } |
| | | |
| | | var ipEndPoint = new IPEndPoint(ipAddresses[0], port); |
| | | if (ipEndPoint == null) |
| | | { |
| | | Debug.Log("IpEndPoint is null"); |
| | | } |
| | | |
| | | var state = new SocketAsyncState(); |
| | | state.IsAsync = true; |
| | | m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), state); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 链接成功时的回调 |
| | | /// </summary> |
| | | /// <param name="_result"></param> |
| | | private void ConnectCallBack(IAsyncResult _result) |
| | | { |
| | | if (!_result.IsCompleted) |
| | | { |
| | | DesignDebug.Log("链接超时!"); |
| | | CloseConnect(); |
| | | } |
| | | else |
| | | { |
| | | if (m_Socket != null && m_Socket.Connected) |
| | | { |
| | | DesignDebug.Log("确认的链接实现"); |
| | | OnConnectSuccess(); |
| | | |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(); |
| | | onConnected = null; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (m_Socket != null) |
| | | { |
| | | m_Socket.Disconnect(true); |
| | | } |
| | | |
| | | onConnected = null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 关闭链接 |
| | | /// </summary> |
| | | public void CloseConnect() |
| | | { |
| | | isStopTreading = true; |
| | | if (m_packageThread != null) |
| | | { |
| | | m_packageThread.Abort(); |
| | | } |
| | | |
| | | if (m_Socket != null && m_Socket.Connected) |
| | | { |
| | | m_Socket.Shutdown(SocketShutdown.Both); |
| | | m_Socket.Close(); |
| | | } |
| | | |
| | | sendQueue.Clear(); |
| | | m_Socket = null; |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 链接成功 |
| | | /// </summary> |
| | | private void OnConnectSuccess() |
| | | { |
| | | if (m_packageThread != null) |
| | | { |
| | | m_packageThread.Abort(); |
| | | m_packageThread = null; |
| | | } |
| | | m_packageThread = new Thread(new ThreadStart(ReceiveInfo)); // 启动线程接收信息 |
| | | m_packageThread.IsBackground = true; |
| | | m_packageThread.Start(); |
| | | isStopTreading = false; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 接收信息 |
| | | /// </summary> |
| | | private void ReceiveInfo() |
| | | { |
| | | int vDataLeng; |
| | | byte[] vBytes; |
| | | |
| | | while (!isStopTreading) |
| | | { |
| | | if (!m_Socket.Connected) |
| | | { |
| | | isStopTreading = true; |
| | | m_Socket.Shutdown(SocketShutdown.Both); |
| | | m_Socket.Close(); |
| | | break; |
| | | } |
| | | |
| | | try |
| | | { |
| | | vDataLeng = m_Socket.Receive(bufferBytes); |
| | | if (vDataLeng <= 0) |
| | | { |
| | | isStopTreading = true; |
| | | m_Socket.Shutdown(SocketShutdown.Both); |
| | | m_Socket.Close(); |
| | | break; |
| | | } |
| | | getBytesTotal += vDataLeng; |
| | | vBytes = new byte[vDataLeng]; |
| | | Array.Copy(bufferBytes, 0, vBytes, 0, vDataLeng); |
| | | ReadInfo(vBytes); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | DesignDebug.Log(e); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 阅读信息 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | private void ReadInfo(byte[] vBytes) |
| | | { |
| | | try |
| | | { |
| | | byte[] fixBytes = vBytes; |
| | | // 如果存在留包,则并包 |
| | | if (fragmentBytes != null && fragmentBytes.Length > 0) |
| | | { |
| | | Array.Resize(ref fixBytes, vBytes.Length + fragmentBytes.Length); |
| | | Array.Copy(fragmentBytes, 0, fixBytes, 0, fragmentBytes.Length); |
| | | Array.Copy(vBytes, 0, fixBytes, fragmentBytes.Length, vBytes.Length); |
| | | } |
| | | fragmentBytes = null; // 清理掉留包 |
| | | // 分包 |
| | | int vReadIndex = 0; // 初始指针 |
| | | byte[] vPackBytes; |
| | | int vLeavingLeng = 0; |
| | | int vBodyLeng = 0; |
| | | int vTotalLeng = fixBytes.Length; |
| | | GameNetPackBasic vNetpack; |
| | | |
| | | while (vReadIndex < vTotalLeng) |
| | | { |
| | | vLeavingLeng = vTotalLeng - vReadIndex; |
| | | if (vLeavingLeng < 6) // 未符合包的最低限度字节量, 留包 |
| | | { |
| | | fragmentBytes = new byte[vLeavingLeng]; |
| | | Array.Copy(fixBytes, vReadIndex, fragmentBytes, 0, vLeavingLeng); |
| | | break; |
| | | } |
| | | vBodyLeng = BitConverter.ToInt32(fixBytes, vReadIndex + 2); |
| | | if (vBodyLeng > vLeavingLeng - 6)// 未完整的包则留包 |
| | | { |
| | | fragmentBytes = new byte[vLeavingLeng]; |
| | | Array.Copy(fixBytes, vReadIndex, fragmentBytes, 0, vLeavingLeng); |
| | | break; |
| | | } |
| | | vPackBytes = new byte[vBodyLeng]; |
| | | Array.Copy(fixBytes, vReadIndex + 6, vPackBytes, 0, vBodyLeng); // 提取包的字节内容 |
| | | // 完整的包则读包 |
| | | vNetpack = PackageRegedit.TransPack(vPackBytes); |
| | | if (vNetpack != null) |
| | | { |
| | | if (DesignDebug.EnableNet) |
| | | { |
| | | DesignDebug.LogNetFormat("收包:{0}", vNetpack.GetType().Name); |
| | | } |
| | | |
| | | GameNetSystem.Instance.PushPackage(vNetpack); |
| | | } |
| | | vReadIndex += 6 + vBodyLeng; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("收包异常:{0}", ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送信息 |
| | | /// </summary> |
| | | /// <param name="vNetPack"></param> |
| | | public void SendInfo(GameNetPackBasic vNetPack) |
| | | { |
| | | if (!Connected) |
| | | return; |
| | | if (vNetPack == null) |
| | | { |
| | | DesignDebug.LogError("要发的信息对象为空"); |
| | | return; |
| | | } |
| | | |
| | | if (DesignDebug.EnableNet) |
| | | { |
| | | DesignDebug.LogNetFormat("发包:{0}", vNetPack.GetType().Name); |
| | | } |
| | | |
| | | if (vNetPack.cmd == (ushort)0x03FE || vNetPack.cmd == (ushort)0x1801) |
| | | { |
| | | } |
| | | |
| | | if (vNetPack.combineBytes == null) |
| | | { |
| | | vNetPack.WriteToBytes(); |
| | | } |
| | | vNetPack.CombineDatas(); |
| | | #if UNITY_EDITOR |
| | | NetPkgCtl.AddNetPkg(vNetPack.vInfoCont, NetPkgType.Client, vNetPack.ToString(), FieldPrint.PrintFields(vNetPack), FieldPrint.PrintFieldsExpand(vNetPack, true)); |
| | | #endif |
| | | sendBytesTotal += vNetPack.combineBytes.Length; |
| | | SendBytes(vNetPack.combineBytes); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送信息 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | public void SendInfo(byte[] vBytes) |
| | | { |
| | | if (!Connected) |
| | | { |
| | | DesignDebug.LogError("尚未与该后端链接!无法发送信息"); |
| | | return; |
| | | } |
| | | if (vBytes == null || vBytes.Length < 2) |
| | | { |
| | | DesignDebug.LogError("要发的信息数据为空或数据不足"); |
| | | return; |
| | | } |
| | | |
| | | vBytes = GameNetEncode.BaseXorAdd(vBytes); |
| | | byte[] vFrameHead = new byte[] { 255, 204 }; |
| | | byte[] vMsgBodyLength = BitConverter.GetBytes(vBytes.Length); |
| | | byte[] vTotal = new byte[vBytes.Length + 6]; |
| | | Array.Copy(vFrameHead, 0, vTotal, 0, vFrameHead.Length); |
| | | Array.Copy(vMsgBodyLength, 0, vTotal, 2, vMsgBodyLength.Length); |
| | | Array.Copy(vBytes, 0, vTotal, 6, vBytes.Length); |
| | | |
| | | SendBytes(vBytes); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送已加密字节 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | public void SendNoEncrypInfo(byte[] vBytes) |
| | | { |
| | | if (!Connected) |
| | | { |
| | | DesignDebug.LogError("尚未与该后端链接!无法发送信息"); |
| | | return; |
| | | } |
| | | if (vBytes == null || vBytes.Length < 2) |
| | | { |
| | | DesignDebug.LogError("要发的信息数据为空或数据不足"); |
| | | return; |
| | | } |
| | | |
| | | SendBytes(vBytes); |
| | | } |
| | | |
| | | Queue<byte[]> sendQueue = new Queue<byte[]>(); |
| | | |
| | | private void SendBytes(byte[] bytes) |
| | | { |
| | | try |
| | | { |
| | | if (sendQueue.Count > 0) |
| | | { |
| | | sendQueue.Enqueue(bytes); |
| | | } |
| | | else |
| | | { |
| | | m_Socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(SendInfoCallBack), m_Socket); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | DesignDebug.LogError("发送时发生异常"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送完成的回调 |
| | | /// </summary> |
| | | /// <param name="vAsyncSend"></param> |
| | | private void SendInfoCallBack(IAsyncResult vAsyncSend) |
| | | { |
| | | try |
| | | { |
| | | if (sendQueue.Count > 0) |
| | | { |
| | | var bytes = sendQueue.Dequeue(); |
| | | m_Socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(SendInfoCallBack), m_Socket); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | DesignDebug.Log(ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | internal class SocketAsyncState |
| | | { |
| | | /// <summary> |
| | | /// 是否完成。 |
| | | /// </summary> |
| | | public bool Completed { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 数据 |
| | | /// </summary> |
| | | public byte[] Data { get; set; } |
| | | /// <summary> |
| | | /// 是否异步 |
| | | /// </summary> |
| | | public bool IsAsync { get; set; } |
| | | } |
| | | |
| | | |
| | | } |
| | | using UnityEngine;
|
| | | using System;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using System.Net;
|
| | | using System.Net.Sockets;
|
| | | using System.Threading;
|
| | |
|
| | | public class ClientSocketController
|
| | | {
|
| | | Socket m_Socket;
|
| | | public Socket socket
|
| | | {
|
| | | get { return m_Socket; }
|
| | | }
|
| | |
|
| | | private int connectWaitTime = 2000; // 10秒
|
| | | private Thread m_packageThread;
|
| | | private byte[] bufferBytes = new byte[4096]; // 4K,单包字节数组缓存
|
| | | private byte[] fragmentBytes; //留包后的内容
|
| | | private long getBytesTotal = 0; //发送的数据总量
|
| | | private long sendBytesTotal = 0; //发送的数据总量
|
| | |
|
| | | public bool Connected { get { return m_Socket == null ? false : m_Socket.Connected; } }
|
| | |
|
| | | public bool isStopTreading { get; private set; }
|
| | |
|
| | | string ip;
|
| | | int port;
|
| | | Action onConnected = null;
|
| | |
|
| | | public ClientSocketController()
|
| | | {
|
| | | }
|
| | |
|
| | | public void Connect(string _ip, int _port, Action _onConnected)
|
| | | {
|
| | | try
|
| | | {
|
| | | ip = _ip;
|
| | | port = _port;
|
| | | onConnected = _onConnected;
|
| | | Dns.BeginGetHostAddresses(_ip, OnGetHostAddresses, null);
|
| | | }
|
| | | catch (Exception e)
|
| | | {
|
| | | DebugEx.LogError(e.Message);
|
| | | }
|
| | | }
|
| | |
|
| | | private void OnGetHostAddresses(IAsyncResult _result)
|
| | | {
|
| | | var ipAddresses = Dns.EndGetHostAddresses(_result);
|
| | |
|
| | | if (ipAddresses[0].AddressFamily == AddressFamily.InterNetworkV6)
|
| | | {
|
| | | DebugEx.Log("当前使用的网络: IPV6");
|
| | | m_Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
|
| | | }
|
| | | else
|
| | | {
|
| | | DebugEx.Log("当前使用的网络: IPV4");
|
| | | m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
| | | }
|
| | |
|
| | | var ipEndPoint = new IPEndPoint(ipAddresses[0], port);
|
| | | if (ipEndPoint == null)
|
| | | {
|
| | | Debug.Log("IpEndPoint is null");
|
| | | }
|
| | |
|
| | | var state = new SocketAsyncState();
|
| | | state.IsAsync = true;
|
| | | m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), state);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 链接成功时的回调
|
| | | /// </summary>
|
| | | /// <param name="_result"></param>
|
| | | private void ConnectCallBack(IAsyncResult _result)
|
| | | {
|
| | | if (!_result.IsCompleted)
|
| | | {
|
| | | DebugEx.Log("链接超时!");
|
| | | CloseConnect();
|
| | | }
|
| | | else
|
| | | {
|
| | | if (m_Socket != null && m_Socket.Connected)
|
| | | {
|
| | | DebugEx.Log("确认的链接实现");
|
| | | OnConnectSuccess();
|
| | |
|
| | | if (onConnected != null)
|
| | | {
|
| | | onConnected();
|
| | | onConnected = null;
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | if (m_Socket != null)
|
| | | {
|
| | | m_Socket.Disconnect(true);
|
| | | }
|
| | |
|
| | | onConnected = null;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 关闭链接
|
| | | /// </summary>
|
| | | public void CloseConnect()
|
| | | {
|
| | | try
|
| | | {
|
| | | isStopTreading = true;
|
| | | if (m_packageThread != null)
|
| | | {
|
| | | m_packageThread.Abort();
|
| | | }
|
| | | }
|
| | | catch (System.Exception ex)
|
| | | {
|
| | | DebugEx.Log(ex);
|
| | | }
|
| | |
|
| | | try
|
| | | {
|
| | | if (m_Socket != null && m_Socket.Connected)
|
| | | {
|
| | | m_Socket.Shutdown(SocketShutdown.Both);
|
| | | m_Socket.Close();
|
| | | }
|
| | |
|
| | | }
|
| | | catch (System.Exception ex)
|
| | | {
|
| | | DebugEx.Log(ex);
|
| | | }
|
| | |
|
| | | sendQueue.Clear();
|
| | | m_Socket = null;
|
| | |
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 链接成功
|
| | | /// </summary>
|
| | | private void OnConnectSuccess()
|
| | | {
|
| | | if (m_packageThread != null)
|
| | | {
|
| | | m_packageThread.Abort();
|
| | | m_packageThread = null;
|
| | | }
|
| | | m_packageThread = new Thread(new ThreadStart(ReceiveInfo)); // 启动线程接收信息
|
| | | m_packageThread.IsBackground = true;
|
| | | m_packageThread.Start();
|
| | | isStopTreading = false;
|
| | | }
|
| | |
|
| | |
|
| | | /// <summary>
|
| | | /// 接收信息
|
| | | /// </summary>
|
| | | private void ReceiveInfo()
|
| | | {
|
| | | int vDataLeng;
|
| | | byte[] vBytes;
|
| | |
|
| | | while (!isStopTreading)
|
| | | {
|
| | | if (!m_Socket.Connected)
|
| | | {
|
| | | isStopTreading = true;
|
| | | m_Socket.Shutdown(SocketShutdown.Both);
|
| | | m_Socket.Close();
|
| | | break;
|
| | | }
|
| | |
|
| | | try
|
| | | {
|
| | | vDataLeng = m_Socket.Receive(bufferBytes);
|
| | | if (vDataLeng <= 0)
|
| | | {
|
| | | isStopTreading = true;
|
| | | m_Socket.Shutdown(SocketShutdown.Both);
|
| | | m_Socket.Close();
|
| | | break;
|
| | | }
|
| | | getBytesTotal += vDataLeng;
|
| | | vBytes = new byte[vDataLeng];
|
| | | Array.Copy(bufferBytes, 0, vBytes, 0, vDataLeng);
|
| | | ReadInfo(vBytes);
|
| | | }
|
| | | catch (Exception e)
|
| | | {
|
| | | DebugEx.Log(e);
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 阅读信息
|
| | | /// </summary>
|
| | | /// <param name="vBytes"></param>
|
| | | private void ReadInfo(byte[] vBytes)
|
| | | {
|
| | | try
|
| | | {
|
| | | byte[] fixBytes = vBytes;
|
| | | // 如果存在留包,则并包
|
| | | if (fragmentBytes != null && fragmentBytes.Length > 0)
|
| | | {
|
| | | Array.Resize(ref fixBytes, vBytes.Length + fragmentBytes.Length);
|
| | | Array.Copy(fragmentBytes, 0, fixBytes, 0, fragmentBytes.Length);
|
| | | Array.Copy(vBytes, 0, fixBytes, fragmentBytes.Length, vBytes.Length);
|
| | | }
|
| | | fragmentBytes = null; // 清理掉留包
|
| | | // 分包
|
| | | int vReadIndex = 0; // 初始指针
|
| | | byte[] vPackBytes;
|
| | | int vLeavingLeng = 0;
|
| | | int vBodyLeng = 0;
|
| | | int vTotalLeng = fixBytes.Length;
|
| | | GameNetPackBasic vNetpack;
|
| | |
|
| | | while (vReadIndex < vTotalLeng)
|
| | | {
|
| | | vLeavingLeng = vTotalLeng - vReadIndex;
|
| | | if (vLeavingLeng < 6) // 未符合包的最低限度字节量, 留包
|
| | | {
|
| | | fragmentBytes = new byte[vLeavingLeng];
|
| | | Array.Copy(fixBytes, vReadIndex, fragmentBytes, 0, vLeavingLeng);
|
| | | break;
|
| | | }
|
| | | vBodyLeng = BitConverter.ToInt32(fixBytes, vReadIndex + 2);
|
| | | if (vBodyLeng > vLeavingLeng - 6)// 未完整的包则留包
|
| | | {
|
| | | fragmentBytes = new byte[vLeavingLeng];
|
| | | Array.Copy(fixBytes, vReadIndex, fragmentBytes, 0, vLeavingLeng);
|
| | | break;
|
| | | }
|
| | | vPackBytes = new byte[vBodyLeng];
|
| | | Array.Copy(fixBytes, vReadIndex + 6, vPackBytes, 0, vBodyLeng); // 提取包的字节内容
|
| | | // 完整的包则读包
|
| | | vNetpack = PackageRegedit.TransPack(vPackBytes);
|
| | | if (vNetpack != null)
|
| | | {
|
| | | if (DebugEx.EnableNetLog)
|
| | | {
|
| | | DebugEx.NetLogFormat("收包:{0}", vNetpack.GetType().Name);
|
| | | }
|
| | |
|
| | | GameNetSystem.Instance.PushPackage(vNetpack);
|
| | | }
|
| | | vReadIndex += 6 + vBodyLeng;
|
| | | }
|
| | | }
|
| | | catch (Exception ex)
|
| | | {
|
| | | Debug.LogFormat("收包异常:{0}", ex);
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 发送信息
|
| | | /// </summary>
|
| | | /// <param name="vNetPack"></param>
|
| | | public void SendInfo(GameNetPackBasic vNetPack)
|
| | | {
|
| | | if (!Connected)
|
| | | return;
|
| | | if (vNetPack == null)
|
| | | {
|
| | | DebugEx.LogError("要发的信息对象为空");
|
| | | return;
|
| | | }
|
| | |
|
| | | if (DebugEx.EnableNetLog)
|
| | | {
|
| | | DebugEx.NetLogFormat("发包:{0}", vNetPack.GetType().Name);
|
| | | }
|
| | |
|
| | | if (vNetPack.cmd == (ushort)0x03FE || vNetPack.cmd == (ushort)0x1801)
|
| | | {
|
| | | }
|
| | |
|
| | | if (vNetPack.combineBytes == null)
|
| | | {
|
| | | vNetPack.WriteToBytes();
|
| | | }
|
| | | vNetPack.CombineDatas();
|
| | | #if UNITY_EDITOR
|
| | | NetPkgCtl.AddNetPkg(vNetPack.vInfoCont, NetPkgType.Client, vNetPack.ToString(), FieldPrint.PrintFields(vNetPack), FieldPrint.PrintFieldsExpand(vNetPack, true));
|
| | | #endif
|
| | | sendBytesTotal += vNetPack.combineBytes.Length;
|
| | | SendBytes(vNetPack.combineBytes);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 发送信息
|
| | | /// </summary>
|
| | | /// <param name="vBytes"></param>
|
| | | public void SendInfo(byte[] vBytes)
|
| | | {
|
| | | if (!Connected)
|
| | | {
|
| | | DebugEx.LogError("尚未与该后端链接!无法发送信息");
|
| | | return;
|
| | | }
|
| | | if (vBytes == null || vBytes.Length < 2)
|
| | | {
|
| | | DebugEx.LogError("要发的信息数据为空或数据不足");
|
| | | return;
|
| | | }
|
| | |
|
| | | vBytes = GameNetEncode.BaseXorAdd(vBytes);
|
| | | byte[] vFrameHead = new byte[] { 255, 204 };
|
| | | byte[] vMsgBodyLength = BitConverter.GetBytes(vBytes.Length);
|
| | | byte[] vTotal = new byte[vBytes.Length + 6];
|
| | | Array.Copy(vFrameHead, 0, vTotal, 0, vFrameHead.Length);
|
| | | Array.Copy(vMsgBodyLength, 0, vTotal, 2, vMsgBodyLength.Length);
|
| | | Array.Copy(vBytes, 0, vTotal, 6, vBytes.Length);
|
| | |
|
| | | SendBytes(vTotal);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 发送已加密字节
|
| | | /// </summary>
|
| | | /// <param name="vBytes"></param>
|
| | | public void SendNoEncrypInfo(byte[] vBytes)
|
| | | {
|
| | | if (!Connected)
|
| | | {
|
| | | DebugEx.LogError("尚未与该后端链接!无法发送信息");
|
| | | return;
|
| | | }
|
| | | if (vBytes == null || vBytes.Length < 2)
|
| | | {
|
| | | DebugEx.LogError("要发的信息数据为空或数据不足");
|
| | | return;
|
| | | }
|
| | |
|
| | | SendBytes(vBytes);
|
| | | }
|
| | |
|
| | | Queue<byte[]> sendQueue = new Queue<byte[]>();
|
| | |
|
| | | private void SendBytes(byte[] bytes)
|
| | | {
|
| | | try
|
| | | {
|
| | | if (sendQueue.Count > 0)
|
| | | {
|
| | | sendQueue.Enqueue(bytes);
|
| | | }
|
| | | else
|
| | | {
|
| | | m_Socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(SendInfoCallBack), m_Socket);
|
| | | }
|
| | | }
|
| | | catch
|
| | | {
|
| | | DebugEx.LogError("发送时发生异常");
|
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 发送完成的回调
|
| | | /// </summary>
|
| | | /// <param name="vAsyncSend"></param>
|
| | | private void SendInfoCallBack(IAsyncResult vAsyncSend)
|
| | | {
|
| | | try
|
| | | {
|
| | | if (sendQueue.Count > 0)
|
| | | {
|
| | | var bytes = sendQueue.Dequeue();
|
| | | m_Socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(SendInfoCallBack), m_Socket);
|
| | | }
|
| | | }
|
| | | catch (Exception ex)
|
| | | {
|
| | | DebugEx.Log(ex);
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | internal class SocketAsyncState
|
| | | {
|
| | | /// <summary>
|
| | | /// 是否完成。
|
| | | /// </summary>
|
| | | public bool Completed { get; set; }
|
| | |
|
| | | /// <summary>
|
| | | /// 数据
|
| | | /// </summary>
|
| | | public byte[] Data { get; set; }
|
| | | /// <summary>
|
| | | /// 是否异步
|
| | | /// </summary>
|
| | | public bool IsAsync { get; set; }
|
| | | }
|
| | |
|
| | |
|
| | | }
|