private void receiveDataAsync(IAsyncResult ar) { IPEndPoint remote = null; byte[] buffer = null; try { buffer = server.EndReceive(ar, ref remote); this.TotalBytesReceived += buffer.Length; var peer = this.Peers.Where(p => p.IP == remote.Address.ToString() && p.Port == remote.Port).FirstOrDefault(); if (peer != null) { peer.TotalBytesReceived += buffer.Length; peer.LastReceivedTime = Time.EpochTime; } LogHelper.Debug(DateTime.Now + " Received cmd from " + remote.Address + ", Data:" + Base16.Encode(buffer)); var prefix = new byte[4]; var suffix = new byte[4]; bool isBufferEnd = false; var key = remote.Address + ":" + remote.Port; if (buffer.Length > 4) { Array.Copy(buffer, 0, prefix, 0, 4); Array.Copy(buffer, buffer.Length - 4, suffix, 0, 4); if (!this.receivedMessageBuffer.ContainsKey(key)) { this.receivedMessageBuffer.Add(key, new List <byte>()); } //first data package if (P2PCommand.BytesEquals(P2PCommand.DefaultPrefixBytes, prefix)) { this.receivedMessageBuffer[key] = new List <byte>(); this.receivedMessageBuffer[key].AddRange(buffer); //last data package if (P2PCommand.BytesEquals(P2PCommand.DefaultSuffixBytes, suffix)) { isBufferEnd = true; } else { } } else if (P2PCommand.BytesEquals(P2PCommand.DefaultSuffixBytes, suffix)) { this.receivedMessageBuffer[key].AddRange(buffer); isBufferEnd = true; } //other data package else { this.receivedMessageBuffer[key].AddRange(buffer); } } else { this.receivedMessageBuffer[key].AddRange(buffer); isBufferEnd = true; } if (isBufferEnd) { var command = P2PCommand.ConvertBytesToMessage(this.receivedMessageBuffer[key].ToArray()); P2PState state = new P2PState(); state.IP = remote.Address.ToString(); state.Port = remote.Port; state.Command = command; if (command != null) { LogHelper.Debug(DateTime.Now + " Received cmd from " + remote.Address + ", Command:" + command.CommandName); if (peer == null && command.CommandName != CommandNames.P2P.Ping) { this.ConnectToNewPeer(remote.Address.ToString(), remote.Port); return; } switch (command.CommandName) { case CommandNames.P2P.Ping: this.pingMsgHandle(state); break; case CommandNames.P2P.Pong: this.pongMsgHandle(state); break; case CommandNames.P2P.Version: this.versionMsgHandle(state); break; case CommandNames.P2P.VerAck: this.verAckMsgHandle(state); break; case CommandNames.P2P.GetAddr: this.getAddrMsgHandle(state); break; case CommandNames.P2P.Addr: this.addrMsgHandle(state); break; case CommandNames.P2P.Heartbeat: this.heartbeatMsgHandle(state); break; case CommandNames.Other.Reject: this.rejectMsgHandle(state); break; default: raiseDataReceived(state); break; } } } } catch (Exception ex) { LogHelper.Error(ex.Message, ex); raiseOtherException(null); } finally { if (this.IsRunning && this.server != null) { server.BeginReceive(receiveDataAsync, null); } } }