/// <summary> /// 异步读取包体回调函数 /// </summary> /// <param name="asyncResult">读取结果</param> void ReadAsyncCallBackPack(IAsyncResult asyncResult) { try { int dataLen = mNetStream.EndRead(asyncResult); if (dataLen == 0) { Loom.QueueOnMainThread(() => { Disconnect("recv 0 bytes and server disconnected"); }); return; } AsyncData data = (AsyncData)asyncResult.AsyncState; if (data.pos + dataLen == data.buff.Length) //读取完毕后放入队列,开始读取下一个包 { Pkt p; p.data = data.buff; p.messId = data.messId; lock (mRecvPacks) { //Debug.LogFormat("recv data {0} {1}", data.buff.Length, p.messId); mRecvPacks.Enqueue(p); } BeginPackRead(); } else //没读取完需要继续读取 { data.pos += dataLen; //Debug.LogFormat("continue recv data {0} {1}", data.buff.Length, data.pos); mNetStream.BeginRead(data.buff, data.pos, data.buff.Length - data.pos, new AsyncCallback(ReadAsyncCallBackPack), data); } } catch (Exception ex) { Loom.QueueOnMainThread(() => { Disconnect(ex.ToString()); }); } }
/// <summary> /// 当连接完成后回调处理 /// </summary> /// <param name="asyncResult">异步结果</param> void OnConnectCallback(IAsyncResult asyncResult) { try { TcpClient tcpclient = asyncResult.AsyncState as TcpClient; if (tcpclient.Client != null) { tcpclient.EndConnect(asyncResult); } } catch (Exception ex) { Loom.QueueOnMainThread(() => { if (mOnConnect != null) { mOnConnect.Invoke(false, ex.ToString()); //发生了异常,通知连接失败 } }); } finally { mNetStream = mTcpClient.GetStream(); BeginPackRead(); //开始异步读取包 Loom.QueueOnMainThread(() => //到主线程中通知连接成功 { if (IsInvoking("ConnectTimeOutCheck")) { CancelInvoke("ConnectTimeOutCheck"); } mIsConnected = true; if (mOnConnect != null) { mOnConnect.Invoke(true, ""); } }); } }
/// <summary> /// 开始异步读取包 /// </summary> void BeginPackRead() { AsyncData data = new AsyncData { buff = new byte[PACK_HEAD_SIZE + MSG_ID_SIZE], //包大小加上ID一共6个字节 pos = 0 }; try { mNetStream.BeginRead(data.buff, 0, data.buff.Length, new AsyncCallback(ReadAsyncCallBackPackHead), data); } catch (Exception ex) { Loom.QueueOnMainThread(() => { Disconnect(ex.ToString()); }); } }
/// <summary> /// 读取包头的异步回调 /// </summary> /// <param name="asyncResult">异步参数</param> void ReadAsyncCallBackPackHead(IAsyncResult asyncResult) { try { int dataLen = mNetStream.EndRead(asyncResult); if (dataLen == 0) { Loom.QueueOnMainThread(() => { Disconnect("recv 0 bytes and server disconnected"); }); return; } AsyncData head_data = (AsyncData)asyncResult.AsyncState; if (head_data.pos + dataLen == head_data.buff.Length) //如果包头读取完毕则开始读取数据部分 { int packLen = new BinaryReader(new MemoryStream(head_data.buff)).ReadInt32(); short msgID = new BinaryReader(new MemoryStream(head_data.buff, PACK_HEAD_SIZE, MSG_ID_SIZE)).ReadInt16(); //Debug.LogFormat("recv head {0} {1} {2}", dataLen, packLen, msgID); if (packLen == MSG_ID_SIZE) //表示包体没有数据,只有一个消息ID,这时发起新的包异步读取 { Pkt p; p.data = new byte[0]; p.messId = msgID; lock (mRecvPacks) { mRecvPacks.Enqueue(p); } BeginPackRead(); } else if (packLen < MSG_ID_SIZE) { throw new Exception("recv pack len " + packLen); //服务器发送过来一个错误的包大小 } else //发起异步读取包体 { AsyncData pack_data = new AsyncData { buff = new byte[packLen - MSG_ID_SIZE], //计算包体大小需要减掉消息id所占的2个字节 pos = 0, messId = msgID }; mNetStream.BeginRead(pack_data.buff, 0, pack_data.buff.Length, new AsyncCallback(ReadAsyncCallBackPack), pack_data); } } else //没读取完则继续读取包头剩余部分 { head_data.pos += dataLen; //Debug.LogFormat("continue recv head {0} {1}", head_data.buff.Length, head_data.pos); mNetStream.BeginRead(head_data.buff, head_data.pos, head_data.buff.Length - head_data.pos, new AsyncCallback(ReadAsyncCallBackPackHead), head_data); } } catch (Exception ex) { Loom.QueueOnMainThread(() => { Disconnect(ex.ToString()); }); return; } }