skip to content

When an RPC protocol is bound to a transport, what must the binding supply that the call model itself leaves out?

level: middleimportance: should knowfreq 13%

answer

  1. messages, not delivery
  2. boundaries on a byte stream
  3. datagrams lose and duplicate
  4. finding the server is separate

basics

~20 s

The call model defines messages, not delivery. A binding supplies message boundaries on a byte stream, the transport's size limits, how replies pair with calls and, on datagrams, timeouts, retransmission and duplicate detection; finding the server is separate again.

solid answer

~50 s

An RPC protocol specifies what a call and a reply contain; the binding decides how they travel. RFC 5531 says ONC RPC's scope "excludes how a message is passed from one process to another" and that RPC "does not try to implement any kind of reliability". So the binding must supply: **delimiting** messages on a byte stream (ONC RPC's record marking over TCP), respecting a datagram transport's **message-size limit**, **correlation** (the transport pairs request and response, or an identifier in each message does), and on an unreliable transport the **timeout, retransmission and duplicate detection** the transport lacks. Client and server must agree on the transport. Locating the server - which host and port serve a program - is a further step RFC 5531 explicitly leaves to higher-level software. The same JSON-RPC 2.0 message can ride HTTP, a socket or an in-process channel because its specification is transport agnostic.

go deeper

for a junior

Recall that an RPC protocol defines the messages and a transport carries them, and that the two are chosen separately.

for a middle

List what a binding must settle - delimiting, size, reliability, correlation, addressing - and contrast a byte-stream binding with a datagram one.

for a senior

Explain why a reliable transport still needs timeouts and reconnection, and how moving a service between transports changes failure behaviour in production.

for a principal

Weigh binding one RPC layer to several transports against standardising on one, considering operability, client reach and the cost of each binding's failure modes.

## Two layers: the message protocol and the transport An RPC protocol defines **messages**: what a call contains (procedure identifier, arguments, call identifier, credentials) and what a reply contains (status, result or error). It usually does not define how those bytes get from one process to the other. RFC 5531 is explicit for ONC RPC: its scope "excludes how a message is passed from one process to another, and includes only the specification and interpretation of messages", and "the client and server must agree on their transport protocol choices". JSON-RPC 2.0 says the same about itself: it is "transport agnostic", usable within one process, over sockets or over HTTP. The **binding** is the agreement that maps the message protocol onto one transport. Whatever the call model leaves out, the binding must supply. ## What a binding has to decide | Concern | Byte stream (e.g. TCP) | Datagram (e.g. UDP) | Request-response (e.g. HTTP) | |---|---|---|---| | Message boundaries | Must be added - the stream has none | One datagram carries one message | The protocol delimits each request and response body | | Size | No inherent limit | Bounded by the datagram size | Set by the protocol and by implementations | | Loss and duplicates | The transport retransmits and orders | The RPC layer must time out, retransmit and detect duplicates | The transport is reliable; replies can still never come | | Pairing reply to call | Identifier in each message | Identifier in each message | The exchange pairs them; a batch of calls in one request still needs identifiers | Concretely, a binding settles: - **delimiting** - how a receiver finds where one message ends; - **size** - what happens to a message larger than the transport accepts; - **reliability** - who times out, retransmits and drops duplicates; - **correlation** - whether the transport or a message field pairs replies with calls; - **addressing** - how a call reaches the right process, and which content type or port identifies the protocol. ## Record marking: a byte-stream binding in miniature TCP delivers an ordered stream of bytes with no message boundaries, so RFC 5531 adds **record marking** for it: 1. One RPC message is one **record**, made of one or more **fragments**. 2. Each fragment starts with a four-byte header: the highest bit says whether this is the last fragment, the low 31 bits give the fragment's data length (0 to 2^31 - 1 bytes). 3. The receiver reads headers and data until it sees the last-fragment bit, then hands the whole record to the RPC layer. Over UDP no record marking is used: each datagram already is one message, and the transport's maximum message size limits how large a call can be. Delimiting a stream is a general framing problem; the RPC-specific point is that a binding must pick an answer. ## Reliability is the binding's problem, not the protocol's RFC 5531 states that RPC "does not try to implement any kind of reliability". On UDP the application "must implement its own time-out, retransmission, and duplicate detection policies"; the transaction identifier `xid` is what lets a server recognise a retransmitted call. On TCP "most of the work is already done", but the RFC warns that an application "still needs time-outs and reconnections to handle server crashes". What a missing reply means for the remote work - whether it ran zero, one or more times - is a separate question about invocation semantics; the binding only decides who does the waiting and resending. ## Binding a client to a server There is a second, older meaning of **binding**: connecting a particular client to a particular server instance. RFC 5531's section "Binding and Rendezvous Independence" says this act "is NOT part of this RPC protocol specification" and is "left up to some higher-level software", comparing RPC to a network's jump-to-subroutine instruction and the binder to the loader. In practice that is a name or port-lookup service, which may itself be reached by RPC. ## Common confusions - "TCP makes timeouts unnecessary" - delivery on a live connection is not an answer from a server that crashed. - "The RPC protocol retransmits lost calls" - in ONC RPC it explicitly does not; the layer above the transport does. - "Changing transport is invisible to the application" - message size, reliability and timeout behaviour all change with it.

  • Why does an RPC binding over TCP still need timeouts?
    A reliable stream guarantees that bytes sent on a live connection arrive in order; it does not guarantee that the server ever answers. The server can crash, hang or lose the connection mid-call. RFC 5531 says that even over a connection-oriented transport an application still needs time-outs and reconnections to handle server crashes.
  • How does ONC RPC's record marking split one message into fragments?
    Each fragment starts with a four-byte header. Its highest bit is set on the record's last fragment, and the remaining 31 bits give that fragment's data length, from 0 to 2^31 - 1 bytes. A record - one RPC message - is one or more fragments; RFC 5531 notes this header is not in XDR standard form.
  • Is finding the server's address part of the RPC protocol?
    Not in ONC RPC: RFC 5531 says binding a client to a service and its transport parameters is not part of the protocol specification and is left to higher-level software, typically a lookup service the client asks before calling.

saying these in an interview costs you the question

  • Running RPC over TCP makes timeouts unnecessary because delivery is guaranteed.
  • The ONC RPC protocol itself retransmits lost calls on any transport.
  • A datagram binding needs record marking just like a byte-stream binding.
  • The RPC specification also defines how a client finds the server's host and port.
  • Switching an RPC service from UDP to TCP changes nothing the application sees.