/// <summary> /// Writes message to to the output stream. /// </summary> /// <exception cref="IOException"/> public void Serialize(Message message, Stream @out) { string name; if (!_names.TryGetValue(message.GetType(), out name)) { throw new Exception("BitcoinSerializer doesn't currently know how to serialize " + message.GetType()); } var header = new byte[4 + _commandLen + 4 + (_usesChecksumming ? 4 : 0)]; Utils.Uint32ToByteArrayBe(_params.PacketMagic, header, 0); // The header array is initialized to zero so we don't have to worry about // NULL terminating the string here. for (var i = 0; i < name.Length && i < _commandLen; i++) { header[4 + i] = (byte) name[i]; } var payload = message.BitcoinSerialize(); Utils.Uint32ToByteArrayLe((uint) payload.Length, header, 4 + _commandLen); if (_usesChecksumming) { var hash = Utils.DoubleDigest(payload); Array.Copy(hash, 0, header, 4 + _commandLen + 4, 4); } @out.Write(header); @out.Write(payload); if (_log.IsDebugEnabled) _log.DebugFormat("Sending {0} message: {1}", name, Utils.BytesToHexString(header) + Utils.BytesToHexString(payload)); }
/// <summary> /// Writes the given message out over the network using the protocol tag. For a Transaction /// this should be "tx" for example. It's safe to call this from multiple threads simultaneously, /// the actual writing will be serialized. /// </summary> /// <exception cref="IOException"/> public virtual void WriteMessage(Message message) { lock (_out) { _serializer.Serialize(message, _out); } }