public static async Task<Message> DeserializeFromStreamAsync(Stream stream) { byte[] buffer = new byte[sizeof(uint) + 12 + sizeof(uint) + sizeof(uint)]; await stream.ReadAsync(buffer, 0, buffer.Length); Message message = new Message(); using (MemoryStream ms = new MemoryStream(buffer, false)) using (BinaryReader reader = new BinaryReader(ms)) { if (reader.ReadUInt32() != Magic) throw new FormatException(); message.Command = reader.ReadFixedString(12); uint length = reader.ReadUInt32(); if (length > 0x02000000) throw new FormatException(); message.Checksum = reader.ReadUInt32(); message.Payload = new byte[length]; } await stream.ReadAsync(message.Payload, 0, message.Payload.Length); return message; }
private async Task<bool> SendMessageAsync(Message message) { return await Task.Run(() => { return SendMessage(message); }); }
private bool SendMessage(Message message) { if (!connected) throw new InvalidOperationException(); if (disposed > 0) return false; try { lock (writer) { writer.Write(message); } return true; } catch (ObjectDisposedException) { } catch (IOException) { Disconnect(true); } return false; }
private void OnMessageReceived(Message message) { switch (message.Command) { case "addr": OnAddrMessageReceived(message.Payload.AsSerializable<AddrPayload>()); break; case "block": OnNewInventory(message.Payload.AsSerializable<Block>()); break; case "consrequest": OnNewInventory(message.Payload.AsSerializable<BlockConsensusRequest>()); break; case "consresponse": OnNewInventory(message.Payload.AsSerializable<BlockConsensusResponse>()); break; case "getaddr": OnGetAddrMessageReceived(); break; case "getblocks": OnGetBlocksMessageReceived(message.Payload.AsSerializable<GetBlocksPayload>()); break; case "getdata": OnGetDataMessageReceived(message.Payload.AsSerializable<GetDataPayload>()); break; case "getheaders": OnGetHeadersMessageReceived(message.Payload.AsSerializable<GetBlocksPayload>()); break; case "inv": OnInvMessageReceived(message.Payload.AsSerializable<InvPayload>()); break; case "ping": OnPingMessageReceived(message.Payload); break; case "tx": OnNewInventory(Transaction.DeserializeFrom(message.Payload)); break; case "alert": case "headers": case "pong": //暂时忽略 break; case "verack": case "version": default: Disconnect(true); break; } }
private async Task<bool> SendMessageAsync(Message message) { if (!connected) throw new InvalidOperationException(); if (disposed > 0) return false; byte[] buffer = message.ToArray(); try { await stream.WriteAsync(buffer, 0, buffer.Length); return true; } catch (ObjectDisposedException) { } catch (IOException) { Disconnect(true); } return false; }