Every request-response system needs a way to match a reply to its original request. Over a single TCP connection that is easy: the response comes back on the same socket. But once you add connection pooling, multiplexing, or async clients, you need correlation. HTTP/2 tags each request with a stream ID so many requests can share one connection and the right responses still get matched. gRPC, which runs on HTTP/2, does the same.
The caller almost always sets a timeout. If the server does not respond within, say, 30 seconds, the client gives up and treats it as a failure rather than waiting forever. This is critical because a network can drop a packet or a server can hang, and a client with no timeout will block one of its threads or connections indefinitely. Real clients pair timeouts with retries and sometimes a circuit breaker.
Status codes carry the outcome. HTTP uses numbers like 200 for success, 404 for not found, and 503 when the server is overloaded. gRPC has its own set such as OK, NOT_FOUND, and DEADLINE_EXCEEDED. The response also carries the payload, usually JSON, Protocol Buffers, or plain bytes, plus headers describing content type and caching rules.