java.lang.Object
org.klomp.snark.Message

class Messageextends Object
Represents a BitTorrent protocol message for peer communication.

This class encapsulates all BitTorrent protocol message types including:

  • Control messages: keep-alive, choke, unchoke, interested, uninterested
  • Piece messages: have, bitfield, request, piece, cancel
  • Extension messages for protocol extensions
  • Fast peer extension messages (BEP 6)
  • DHT messages (BEP 5, BEP 52)

Messages are created and queued for sending through a DataOutputStream. The sendMessage() method translates messages to wire format.

Message structure includes:

  • type - The message type byte
  • piece - The piece index (for have, request, piece, cancel)
  • begin - The offset within the piece
  • length - The data length
  • data - Optional payload data
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private ByteArray
    Cache-backed buffer owned by this message, non-null between successful load and release.
    private static final ByteCache
    Cache supplying the message buffers.
    private boolean
    Message dropped unsent; the buffer must be released and not stored late.
    private boolean
    Loader completed and returned no data.
    private boolean
    Set exactly once by the winner of the race to execute the loader.
    private boolean
    True while the loader is executing somewhere; cleared by completeLoad().
    (package private) static final byte
    Allow request of a piece without an unchoke (BEP 6).
    private static final int
    Max time the sender thread will wait for an in-flight prefetch before falling back to a drop.
    (package private) final int
    The offset within the piece.
    (package private) static final byte
    Bitfield of pieces the peer has.
    private static final int
    Size of a chunk part.
    (package private) static final byte
    Cancel a previously sent request.
    (package private) static final byte
    Stop sending piece data to the peer.
    (package private) byte[]
    The data payload.
    private final DataLoader
    The loader for a deferred fetch of the message data.
    (package private) static final byte
    BEP 10 extended message, sub-type in the low byte.
    (package private) static final byte
    Reject a hash request (BEP 52).
    (package private) static final byte
    Request merkle hash tree data (BEP 52).
    (package private) static final byte
    Merkle hash tree data (BEP 52).
    (package private) static final byte
    Announce possession of a single piece.
    (package private) static final byte
    Announce possession of every piece (BEP 6).
    (package private) static final byte
    Announce possession of no pieces (BEP 6).
    (package private) static final byte
    Signal that the peer has pieces we want.
    (package private) static final byte
    No-op message sent periodically to keep the connection alive.
    (package private) final int
    The payload length.
    (package private) final int
    The data length.
    (package private) final int
    The data offset.
    (package private) final int
    The piece index.
    (package private) static final byte
    Chunk of a piece in response to a request.
    (package private) static final byte
    Announce the DHT listening port (BEP 5).
    (package private) static final byte
    Reject a previously accepted request (BEP 6).
    (package private) static final byte
    Request a chunk of a piece.
    (package private) static final byte
    Suggest a piece the peer may want (BEP 6).
    (package private) final byte
    The message type.
    (package private) static final byte
    Resume sending piece data to the peer.
    (package private) static final byte
    Signal that we no longer want pieces from the peer.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    (package private)
    Message(byte type)
    For types KEEP_ALIVE, CHOKE, UNCHOKE, INTERESTED, UNINTERESTED, HAVE_ALL, HAVE_NONE.
    (package private)
    Message(byte[] data)
    For type BITFIELD.
    (package private)
    Message(byte type, int piece)
    For types HAVE, PORT, SUGGEST, ALLOWED_FAST.
    (package private)
    Message(byte type, int piece, int begin, int length)
    For types REQUEST, REJECT, CANCEL.
    private
    Message(byte type, int piece, int begin, int length, byte[] data, int off, int len, DataLoader loader)
    Creates a peer protocol message from its fields.
    (package private)
    Message(int id, byte[] data)
    For type EXTENSION.
    (package private)
    Message(int piece, int begin, int length, DataLoader loader)
    For type PIECE with deferred data.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) boolean
    Abort a claimed-but-not-yet-started prefetch because the message was purged unsent, saving the disk read entirely.
    private void
    Wait for an in-flight prefetch to finish.
    (package private) boolean
    Claim exclusive right to execute the loader for this message.
    (package private) void
    Deliver the result of a loader run started after claimLoad() returned true.
    (package private) void
    Mark this message as dropped without sending and release any loaded buffer exactly once.
    (package private) boolean
    Whether the deferred data has been loaded and not yet released.
    (package private) boolean
    Whether this message was dropped without sending.
    private void
    Ensure the deferred PIECE data is available before sending.
    private static void
    Return a cache-acquired buffer to the pool, mirroring Storage.getPiece(int, int, int)'s acquire condition; non-cache-backed partial-read buffers are simply dropped for GC.
    private void
    Release this message's buffer after a successful send.
    private void
    Caller must hold the monitor.
    (package private) ByteArray
    Invoke the deferred loader.
    (package private) boolean
    Sends this message through the given DataOutputStream.
    A string representation of the message.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • KEEP_ALIVE

      static final byte KEEP_ALIVE
      No-op message sent periodically to keep the connection alive.
      See Also:
    • CHOKE

      static final byte CHOKE
      Stop sending piece data to the peer.
      See Also:
    • UNCHOKE

      static final byte UNCHOKE
      Resume sending piece data to the peer.
      See Also:
    • INTERESTED

      static final byte INTERESTED
      Signal that the peer has pieces we want.
      See Also:
    • UNINTERESTED

      static final byte UNINTERESTED
      Signal that we no longer want pieces from the peer.
      See Also:
    • HAVE

      static final byte HAVE
      Announce possession of a single piece.
      See Also:
    • BITFIELD

      static final byte BITFIELD
      Bitfield of pieces the peer has.
      See Also:
    • REQUEST

      static final byte REQUEST
      Request a chunk of a piece.
      See Also:
    • PIECE

      static final byte PIECE
      Chunk of a piece in response to a request.
      See Also:
    • CANCEL

      static final byte CANCEL
      Cancel a previously sent request.
      See Also:
    • PORT

      static final byte PORT
      Announce the DHT listening port (BEP 5).
      See Also:
    • SUGGEST

      static final byte SUGGEST
      Suggest a piece the peer may want (BEP 6).
      See Also:
    • HAVE_ALL

      static final byte HAVE_ALL
      Announce possession of every piece (BEP 6).
      See Also:
    • HAVE_NONE

      static final byte HAVE_NONE
      Announce possession of no pieces (BEP 6).
      See Also:
    • REJECT

      static final byte REJECT
      Reject a previously accepted request (BEP 6).
      See Also:
    • ALLOWED_FAST

      static final byte ALLOWED_FAST
      Allow request of a piece without an unchoke (BEP 6).
      See Also:
    • EXTENSION

      static final byte EXTENSION
      BEP 10 extended message, sub-type in the low byte.
      See Also:
    • HASH_REQUEST

      static final byte HASH_REQUEST
      Request merkle hash tree data (BEP 52).
      See Also:
    • HASHES

      static final byte HASHES
      Merkle hash tree data (BEP 52).
      See Also:
    • HASH_REJECT

      static final byte HASH_REJECT
      Reject a hash request (BEP 52).
      See Also:
    • type

      final byte type
      The message type. Not all fields are used for every message; KEEP_ALIVE has no real wire representation.
    • piece

      final int piece
      The piece index. Used for HAVE, REQUEST, PIECE and CANCEL messages, and also for SUGGEST, REJECT and ALLOWED_FAST; the low byte for EXTENSION messages and the low two bytes for PORT messages.
    • begin

      final int begin
      The offset within the piece. Used for REQUEST, PIECE, CANCEL and REJECT messages.
    • length

      final int length
      The data length.
    • data

      byte[] data
      The data payload. Used for PIECE, BITFIELD and EXTENSION messages.
    • off

      final int off
      The data offset.
    • len

      final int len
      The payload length.
    • dataLoader

      private final DataLoader dataLoader
      The loader for a deferred fetch of the message data.
    • _ba

      private ByteArray _ba
      Cache-backed buffer owned by this message, non-null between successful load and release. It may be loaded off the sender thread by the prefetch executor, so the state transitions below are guarded by this, keeping the sender, the executor and the purge paths in agreement.
    • _loadClaimed

      private boolean _loadClaimed
      Set exactly once by the winner of the race to execute the loader.
    • _pendingLoad

      private boolean _pendingLoad
      True while the loader is executing somewhere; cleared by completeLoad().
    • _failed

      private boolean _failed
      Loader completed and returned no data.
    • _discarded

      private boolean _discarded
      Message dropped unsent; the buffer must be released and not stored late.
    • AWAIT_PREFETCH_TIMEOUT

      private static final int AWAIT_PREFETCH_TIMEOUT
      Max time the sender thread will wait for an in-flight prefetch before falling back to a drop.
      See Also:
    • BUFSIZE

      private static final int BUFSIZE
      Size of a chunk part.
    • _cache

      private static final ByteCache _cache
      Cache supplying the message buffers.
  • Constructor Details

    • Message

      Message(byte type)
      For types KEEP_ALIVE, CHOKE, UNCHOKE, INTERESTED, UNINTERESTED, HAVE_ALL, HAVE_NONE.
      Parameters:
      type - the message type
    • Message

      Message(byte type, int piece)
      For types HAVE, PORT, SUGGEST, ALLOWED_FAST.
      Parameters:
      type - the message type
      piece - the zero-based index of the piece the message refers to
    • Message

      Message(byte type, int piece, int begin, int length)
      For types REQUEST, REJECT, CANCEL.
      Parameters:
      type - the message type
      piece - the zero-based index of the piece requested, rejected or cancelled
      begin - the offset within the piece, in bytes
      length - the number of bytes requested, rejected or cancelled
    • Message

      Message(byte[] data)
      For type BITFIELD.
      Parameters:
      data - the encoded bitfield, sent as the message payload
    • Message

      Message(int id, byte[] data)
      For type EXTENSION.
      Parameters:
      id - the extended message id carried in the extension header
      data - the extension payload
    • Message

      Message(int piece, int begin, int length, DataLoader loader)
      For type PIECE with deferred data.
      Parameters:
      piece - the zero-based index of the piece being sent
      begin - the offset within the piece where the data starts, in bytes
      length - the number of bytes of piece data to send
      loader - the loader that supplies the piece data when it is sent
    • Message

      private Message(byte type, int piece, int begin, int length, byte[] data, int off, int len, DataLoader loader)
      Creates a peer protocol message from its fields.
      Parameters:
      type - the protocol message type
      piece - the piece number
      begin - the offset within the piece
      length - the length of the message data
      data - the data bytes, null for a deferred load
      off - the offset within the data array
      len - the length of the data in the array
      loader - the loader supplying the data
  • Method Details

    • sendMessage

      boolean sendMessage(DataOutputStream dos) throws IOException
      Sends this message through the given DataOutputStream.
      Parameters:
      dos - the output stream to write to
      Returns:
      true if the message was written, false if the deferred data could not be loaded and the message was dropped
      Throws:
      IOException - if an I/O error occurs
    • loadDataForSend

      private void loadDataForSend()
      Ensure the deferred PIECE data is available before sending.

      Exactly one execution site runs the loader, decided by claimLoad(): either this sender thread (inline fallback, the pre-prefetch behavior) or PeerConnectionOut's prefetch task. If a prefetch is in flight, wait briefly for it rather than duplicating the disk read; on timeout or discard the message is dropped and the peer will re-request. The loader always runs outside the message monitor so purge paths are never blocked by disk I/O.

    • runLoader

      ByteArray runLoader()
      Invoke the deferred loader. Must be called only after winning claimLoad(); executes with no locks held so slow reads never block purge paths.
      Returns:
      the loaded buffer, or null on error (a REJECT has already been queued upstream)
    • claimLoad

      boolean claimLoad()
      Claim exclusive right to execute the loader for this message.
      Returns:
      true if the caller must run the loader and later call completeLoad(ByteArray); false if already claimed, completed, failed, discarded, or not loader-backed
    • abortIfDiscarded

      boolean abortIfDiscarded()
      Abort a claimed-but-not-yet-started prefetch because the message was purged unsent, saving the disk read entirely.
      Returns:
      true if the caller should skip loading; pending state is cleared either way
    • completeLoad

      void completeLoad(ByteArray ba)
      Deliver the result of a loader run started after claimLoad() returned true. Stores the buffer unless the message was discarded meanwhile, in which case the buffer is released immediately; failure is recorded so the sender drops the message.
      Parameters:
      ba - the loaded buffer, or null on load failure
    • awaitLoad

      private void awaitLoad()
      Wait for an in-flight prefetch to finish. Bounded so a wedged executor degrades to a dropped block instead of stalling the sender thread indefinitely.
    • discard

      void discard()
      Mark this message as dropped without sending and release any loaded buffer exactly once. Called from all purge paths (choke, cancel, disconnect, queue overflow); safe to call repeatedly and concurrently with an in-flight prefetch.
    • releaseOwned

      private void releaseOwned()
      Release this message's buffer after a successful send. Exactly once; a no-op for messages without loader-loaded data.
    • releaseOwnedInLock

      private void releaseOwnedInLock()
      Caller must hold the monitor.
    • releaseBuffer

      private static void releaseBuffer(ByteArray ba)
      Return a cache-acquired buffer to the pool, mirroring Storage.getPiece(int, int, int)'s acquire condition; non-cache-backed partial-read buffers are simply dropped for GC.
      Parameters:
      ba - the buffer to release
    • isDataReady

      boolean isDataReady()
      Whether the deferred data has been loaded and not yet released.
      Returns:
      true if ready to send without further loading
    • isDiscarded

      boolean isDiscarded()
      Whether this message was dropped without sending.
      Returns:
      true if discarded
    • toString

      public String toString()
      A string representation of the message.
      Overrides:
      toString in class Object
      Returns:
      the type name, with fields in parentheses for data messages