Q1. When Uploading a File, Is It Split Across Multiple HTTP Requests?
Usually, no. A file upload is commonly one HTTP request whose body contains the file data.
The file may be transmitted as many TCP segments and IP packets, but those lower-layer pieces are not separate HTTP requests.
The core distinction is:
HTTP perspective:
one upload request with a body
TCP/IP perspective:
many TCP segments and IP packetsQ2. What is the matching model for file downloads?
An HTTP file download is commonly one HTTP request and one HTTP response whose body carries the file data.
Client -> Server:
GET /big-file.zip HTTP/1.1
Server -> Client:
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Length: 1000000000
<file bytes...>An HTTP file upload follows the same message-versus-transport distinction: it is commonly one HTTP request whose body contains the file data.
Client -> Server:
POST /upload HTTP/1.1
Content-Type: multipart/form-data
Content-Length: 1000000000
<file bytes...>The broader distinction is:
HTTP perspective:
one request or one response
TCP/IP perspective:
many TCP segments and IP packets
Physical/network perspective:
many frames and signals over timeSo a large file is not usually split into many HTTP messages. Usually, one HTTP message has a large body, and lower network layers transmit that body gradually.
Q3. Does the sender build the entire HTTP message before the receiver can receive anything?
No.
The HTTP message is logically one message, but it can be generated, sent, received, and parsed progressively. For an upload, the browser can write the request line and headers first, then continue writing the file body:
Browser:
write HTTP request line
write HTTP headers
write empty line
write file body bytes
write more file body bytes
write more file body bytes
...The operating system does not need the whole HTTP message in memory before it starts sending data. The browser writes bytes to a socket, and the OS TCP stack sends those bytes as a stream.
On the receiving side, the server can read the beginning of the request before the whole file has arrived.
Once the server reads the HTTP headers, it can understand the request method, path, content type, and body length.
For HTTP/1.1, the end of the header section is marked by an empty line:
\r\n\r\nAfter that point, the following bytes are treated as the body according to the HTTP rules.
The key point is that the HTTP message is logically one message, but network processing is streaming and incremental.
Q4. Does TCP know how many total bytes will arrive for an HTTP file upload or download?
No.
TCP does not know the total HTTP body length, the file size, or how many HTTP requests are being carried. TCP only sees a byte stream.
TCP sequence numbers identify positions in that byte stream.
For example:
TCP segment:
sequence number = 1000
payload length = 500
Meaning:
this segment carries bytes 1000 through 1499 in this TCP stream directionTCP can know how many bytes are in the current TCP segment, but it does not know the total application message length.
The total body length is an HTTP-layer concept, usually represented by headers or protocol framing, such as:
Content-Length: 1000000000or, in HTTP/1.1:
Transfer-Encoding: chunkedor, in HTTP/2 and HTTP/3, protocol frames and stream-ending signals.
This distinction matters:
TCP sequence number:
where these bytes belong in the TCP byte stream
HTTP Content-Length:
how many bytes belong to this HTTP message bodyTCP does not need the browser to announce the full HTTP message length before transmission. It can send whatever bytes the browser writes into the socket, in order.
Q5. What identifies a TCP connection, and what role does the TCP sequence number play?
A TCP connection is identified by the endpoint tuple:
source IP
source port
destination IP
destination port
protocolCommonly, this is described as a 4-tuple plus the protocol:
(src IP, src port, dst IP, dst port, TCP)This identifies which TCP connection a segment belongs to.
The sequence number is different. It does not identify the connection by itself. It identifies where a segment’s payload belongs inside one direction of an already identified TCP connection.
A database-like mental model is:
Connection key:
(src IP, src port, dst IP, dst port, TCP)
Sequence number:
byte offset inside that connection's stream directionFor example:
192.168.0.10:52001 -> 93.184.216.34:443
seq = 1000
payload length = 500This means:
In this TCP connection,
in this direction,
bytes 1000 through 1499 have arrived.A sequence number is not globally unique. Different TCP connections can have the same sequence number. Also, a TCP connection has two independent sequence number spaces:
client -> server sequence space
server -> client sequence spaceThe corrected distinction is:
The IP/port tuple finds the TCP connection.
The sequence number places bytes inside that connection.Q6. Why are ports needed when multiple applications or browser tabs communicate with the same server?
Ports help the OS deliver incoming TCP or UDP data to the correct socket inside a host.
A useful simplified model is:
IP address:
which host?
Port:
which transport-layer endpoint on that host?More accurately, the OS does not deliver data directly to “a program” just because of a port. It delivers data to a socket owned by a process.
For example, Chrome and another application can both connect to the same server:
Chrome:
192.168.0.10:52001 -> example.com:443
Another application:
192.168.0.10:52002 -> example.com:443The destination is the same, but the local source ports are different. This lets the OS distinguish the connections when responses return:
example.com:443 -> 192.168.0.10:52001
goes to Chrome's socket
example.com:443 -> 192.168.0.10:52002
goes to the other application's socketHowever, a browser tab is not the same thing as a port.
The more accurate rule is:
A local ephemeral port is assigned per TCP connection, not per browser tab.With HTTP/1.1, a browser may open multiple TCP connections to the same server, so different requests may use different local ports.
With HTTP/2 or HTTP/3, multiple requests from multiple tabs can share one connection. In that case, they can share the same local port.
HTTP/2 uses stream IDs and HTTP/3 uses QUIC streams to distinguish concurrent requests.
The corrected model is that ports distinguish transport-layer sockets or connections, browser tabs are application-level browser concepts, and HTTP/2 or HTTP/3 streams distinguish concurrent requests on one connection.
Q7. If one TCP connection carries many HTTP requests, how does the receiver avoid mixing them up?
TCP does not distinguish the HTTP requests.
TCP only preserves one ordered byte stream. If ten HTTP requests are sent over one TCP connection, TCP still sees only bytes:
byte 1000
byte 1001
byte 1002
byte 1003
...The separation of multiple HTTP requests is handled by the HTTP version above TCP.
In HTTP/1.1, a single TCP connection is mostly used in a sequential request/response style. Multiple requests may reuse the same connection, but true multiplexing is limited.
Ignoring TLS for this mental model, HTTP/2 frames are carried over one TCP connection. HTTP/2 divides messages into frames, and each frame includes a stream ID.
Example:
HTTP/2 frames inside one TCP byte stream:
[HEADERS stream=1]
[HEADERS stream=3]
[DATA stream=1]
[HEADERS stream=5]
[DATA stream=3]
[DATA stream=1]
[DATA stream=5]TCP guarantees that these bytes are delivered to the HTTP/2 layer in order.
Then the HTTP/2 parser reads the frames and demultiplexes them by stream ID:
stream 1:
[HEADERS][DATA][DATA]
stream 3:
[HEADERS][DATA]
stream 5:
[HEADERS][DATA]The responsibilities are separate: TCP delivers one ordered byte stream; HTTP/2 divides that byte stream into frames; stream IDs identify which request or response each frame belongs to.
The word “parallel” can be misleading here. On one TCP connection, bytes are still transmitted in a serial order. HTTP/2 makes multiple requests progress concurrently by interleaving frames from different streams.
The corrected model is: at the transport level there is one ordered byte stream; at the HTTP/2 level there are many logical streams multiplexed over that byte stream.
Q8. Why can one lost TCP segment delay other HTTP/2 requests on the same connection?
Because TCP must deliver bytes to the application in sequence.
Suppose the receiver gets these TCP ranges:
seq 1000-1499 received
seq 1500-1999 lost
seq 2000-2499 received
seq 2500-2999 receivedEven though bytes after 2000 have arrived, TCP cannot normally deliver them to the application before the missing bytes 1500-1999 are recovered.
TCP provides a reliable ordered byte stream, so it must wait for the missing earlier range to be retransmitted.
This can become a problem for HTTP/2 because many HTTP/2 streams share the same TCP byte stream.
For example:
seq 1000-1499:
HTTP/2 frame for stream 1
seq 1500-1999:
lost bytes, maybe part of stream 3
seq 2000-2499:
HTTP/2 frame for stream 5
seq 2500-2999:
HTTP/2 frame for stream 7Even if the data for stream 5 and stream 7 has physically arrived at the TCP layer, the HTTP/2 parser may not receive it yet.
TCP is waiting for the missing earlier bytes. This is TCP head-of-line blocking.
The important correction is that the lost unit is not exactly “one HTTP request’s TCP frame.” More accurately:
A missing TCP byte range blocks later bytes in the same TCP connection,
regardless of which HTTP/2 stream those later bytes belong to.This blocking only affects streams sharing the same TCP connection. If separate TCP connections are used, loss on one connection does not block application delivery on the other connections in the same way.
HTTP/3 reduces this issue by using QUIC instead of TCP. QUIC has independent streams, so loss affecting one QUIC stream does not have to block application delivery of unrelated streams in the same way.