I have written a few simple lines to find out what the browser is sending to the server when requesting a new page. This is from the server (there is no error checking, this is for testing purposes only) . It's written in c++, but you will understand it.
Then I copy this entire code and repeat it 5 times. Now that I have this ready, I start the server and open up my browser (Chrome). In the adressfield am writing localhost:27015, then I press enter. So now lets see what’s happening in the server console …
First, it prints out the number of bytes received (that’s what recv() returns if no errors have occurred). And after that, the entire http request will be printed out. So this is for the first socket. But then it prints zero(0) for the next socket, no message received. And another zero for a third socket, without any message received here either (zero means that the client has closed the socket).
After that, the program is blocked. So apparently Chrome created 3 connections when I wrote localhost:27015 in the browser. The first comes with a full message / http request, but what’s the purpose of the other 2? They both return zero(0). Why do they create 2 additional connections that they then close immediately? (Or have them been paused maybe?)
I also do not think it’s favicon that causes this. Because I get a separate request for favicon, as soon as I respond to the first http request. Note that this happens only with Chrome. IE only creates one connection initially.
Chrome (and other browsers) may open multiple connections to a server in an attempt to improve performance by guarding against failure of the initial TCP SYN handshake, or preemptively opening additional connections in anticipation that there may be multiple resources which could be downloaded in parallel.
Another thing I was thinking about. I get an http request with header Connection: keep-alive. So I respond with the same header (keep-alive). So why does it create a new connection to request favicon instead of requesting favicon on the same connection?
It does not seem like it matters that I respond with Connection: keep-alive
because its faster - the browser is already in its "let's create X amount of connections to load page asap"-state - so it wont bother to manage the overhead to check wich data gets requested from wich connection. Also - as the initial page-load could potentially be a huge multi-MB-file - it would take for ever to load on slow connections. So, it's just a prediction that waiting for the entire initial page request to be completed would take longer - so just open another connection for favicon. If you force slow connection with a virtualized 56k and try to load a huge index page like from some linux mirrors - in fact it really will be faster to just load the favicon in parallel over the second connection as the first would still be blocked by loading the index page. It's just a logical assumption from the real observed increasing size of pages overall.