void EndReceiveFromCallback(IAsyncResult iar) { SocketState state = iar.AsyncState as SocketState; Socket socket = state.Socket; try { int byteRead = socket.EndReceiveFrom(iar, ref state.RemoteEP); MyCentorl.RecvMessage(state.Buffer); } catch (Exception e) { Console.WriteLine("发生异常!异常信息:"); Console.WriteLine(e.Message); } finally { //非常重要:继续异步接收 socket.BeginReceiveFrom( state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.RemoteEP, EndReceiveFromCallback, state); } }
private void OnRecv(IAsyncResult ar) { try { int recvLength = socket.EndReceive(ar); int pkgLength = 0; byte[] data; //如果半包数据不为空 if (null != backupBuffer) { //将半包和后面接收到的数据报拼接起来 data = backupBuffer.Concat(recvBuffer.Take(recvLength).ToArray()).ToArray(); } else { data = recvBuffer.Take(recvLength).ToArray(); } //解决连包问题 while (true) { // 1. recvEvent返回一个完整的数据包长度 pkgLength = MyCentorl.RecvMessage(data); if (pkgLength <= 0 || pkgLength > maxPackage) { //出现异常,连接关闭 state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR; Close(); break; } // 2. 如果正常处理完,则直接启动下次接收 if (pkgLength == data.Length) { ////TraceUtil.Log("正常"); backupBuffer = null; Array.Clear(recvBuffer, 0, recvBuffer.Length); pkgLength = 0; break; } // 3. 如果还未接收完,半包则在偏移处等待 else if (pkgLength > data.Length) { //将半包数据拷贝到backupBuffer ////TraceUtil.Log("半包"); backupBuffer = data.Take(data.Length).ToArray(); break; } // 4. 如果是连包,则循环处理 else if (pkgLength < data.Length) { //自增偏移量并跳过已经处理的包 ////TraceUtil.Log("连包"); data = data.Skip(pkgLength).ToArray(); backupBuffer = null; } else { break; } } StartRecv(); } catch { state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR; Close(); } }