Browser & Network Connections
Lifecycle of Sockets in Browser
author
Written byLakshit NagarPrinciple Software Developer@Oracle India (Ex-ThoughtWorker, IIT Kanpur Alumni)
Browser & Network Connections
Lifecycle of Sockets in Browser
author
Written byLakshit NagarPrinciple Software Developer@Oracle India (Ex-ThoughtWorker, IIT Kanpur Alumni)

Intended Audience

This article is written by a software developer for anyone who is interested in the technical aspects of modern web browsers. Readers do not need any pre-knowledge to understand the content of the article. All you need to know is overview of browser (Browser Fundamentals | Part-2) and basics of HTML & CSS.

Content

  1. Introduction
  2. How Browser Connect to the Internet?
  3. Connection Protocols - TCP/UDP
  4. Connection Adaptor - Sockets
  5. Why Browser Limit Socket Connections?
  6. Lifecycle of sockets


Introduction

We all have used the modern web browsers to some extent (more or less). We use it to watch our favourite movies, games, chatting and what not. But there is one thing without with browser is completely useless (at least due to pupose for which it was created). That thing is it's ability to connect to the Internet. Yes our own world wide web. This raises a curiosity about how this is accomplished? How browsers connects itself to the Internet. In this article we will dig deep into this.


How Browser Connect to the Internet?

Lets view it from top level. On one side we have the Internet, and on the other side we have the browser. Browser Network Layer Language As we can see, there is a difference in the language thay both speak. The Internet (Network) understands only TCP/UDP. These are transport layer protocols (language) to handle how the data is transported between server and client (browser). Whereas a browser understands HTTP. HTTP is an application layer protocol (language) to recieve/send hypertexts from/to a server. Hypertexts are kind of data that browser needs for its application usage.

Who will compromise?

Here, both browser & the Internet is kind of rigid on the protocols they uses, and they has their own reasons. To make both work with each other, we are three possible options:

  1. The Internet implements an adaptor that translates between HTTP and TCP/UDP.
  2. Browser implements an adaptor that translates between HTTP and TCP/UDP.
  3. Both implements an adaptor that translates to a new common language that both understands.
But before selecting any option we must understand one important thing about the Internet and any application such as a browser. The Internet is huge decentralised network. Its only job is to transfer the data. Internet does not even need to bother about what that data represent. In our example the data is hypertext, but this requirement can change if we replace browser with another application lets say video call. Therfore, HTTP is an application specific language whereas, TCP/UDP is kind of universal language that can transfer data (any kind of data). With this we can conclude that second option is the only option. So it is wiser that an application should have an adaptor that translates between HTTP and TCP/UDP. Browser Network Layer Adaptor The another name for this adaptor is Sockets.


Connection Protocols - TCP/UDP

These transport layer protocols are the bus that a data packet (smallest unit of transferrable unit) must board to get from one machine to another around the world. This data packet can be from HTTP, RTCPeerConnection, etc. TCP & UDP, both does the same job, the difference is in how they do it.

Feature

TCP

UDP

Connection status

Requires an established connection to transmit data (connection should be closed once transmission is complete)

Connectionless protocol with no requirements for opening, maintaining, or terminating a connection

Data sequencing

Able to sequence

Unable to sequence

Guaranteed delivery

Can guarantee delivery of data to the destination router

Cannot guarantee delivery of data to the destination

Retransmission of data

Retransmission of lost packets is possible

No retransmission of lost packets

Error checking

Extensive error checking and acknowledgment of data

Basic error checking mechanism using checksums

Method of transfer

Data is read as a byte stream; messages are transmitted to segment boundaries

UDP packets with defined boundaries; sent individually and checked for integrity on arrival

Speed

Slower than UDP

Faster than TCP

Broadcasting

Does not support Broadcasting

Does support Broadcasting

Optimal use

Used by HTTPS, HTTP, SMTP, POP, FTP, etc

Video conferencing, streaming, DNS, VoIP, etc

Table Source: www.lifesize.com

Connection Adaptor - Sockets

TCP Socket Adaptor

The TCP/UDP adaptor we talked in previous sections, is nothing but TCP/UDP Sockets. It opens a door way to the Internet and helps browser to communicate across the world. But for this, every browser need to implement and expose an API to create TCP/UDP sockets. And of course, there is a standard set by W3C organisation. Here is an example of how TCPSocket should be invoked according to the standard.

  • First create a new TCPSocket object.
  • Check for permission, and if not throw SecurityError.
  • If the provided host is invalid, throw, InvalidAccessError.
  • and many more...
These standards pen downs a lot of aspects of API's behaviour that it is difficult ot cover all here. If you want to read more about these standards, you can find it all here https://www.w3.org/TR/tcp-udp-sockets.

Following the standard, chrome exposes the API and it is something like below:

chrome.sockets.tcp.create(properties?: SocketProperties, callback: function)
Here is the detailed design of chrome socket API: https://docs.google.com/document/d/1Xa5nFkIWxkL3hZHvDYWPhT8sZvNeFpCUKNuqIwZHxnE/edit Theoretically it is possible to create as many number of sockets as possible. But browsers imposes some upper limit to optimize the resource and performance. Chrome limits the socket creation as per the origin. It imposes a restriction of six sockets per origin.
https://source.chromium.org/chromium/chromium/src/+/master:net/socket/client_socket_pool_manager.cc;l=51


Why Browser Limit Socket Connections?

The reason why browser imposes a limit is because the servers could not be oveloaded by small number of browsers and end up classifying user as DDoS attacker. Also, according to IETF standards followed by browsers states that browsers should limit the number of simultaneous connections. Here is the reasoning behind it:

Clients SHOULD limit the number of simultaneous connections that they maintain to a given server.

Previous revisions of HTTP gave a specific number of connections as a ceiling, but this was found to be impractical for many applications. As a result, this specification does not mandate a particular maximum number of connections, but instead encourages clients to be conservative when opening multiple connections.

Multiple connections are typically used to avoid the "head-of-line blocking" problem, wherein a request that takes significant server- side processing and/or has a large payload blocks subsequent requests on the same connection. However, each connection consumes server resources. Furthermore, using multiple connections can cause undesirable side effects in congested networks.

Note that servers might reject traffic that they deem abusive, including an excessive number of connections from a client.
Previously, browsers had the common limit of only 2 connections. This may be sufficient in the beginning day of web pages as most of the contents are delivered in a single page load. However, it soon become the bottleneck when css, javascript getting popular. Because of this, companies started to increase this limit for modern browsers.


Lifecycle of sockets

Sockets follows a defined processes in its lifetime. From creation to close, there are various processes that helps accomplishing the task of communication.

Create

This stage creates a TCP/UDP socket according to provided options, passed as SocketProperties, in which you can pass {buffer: 4096, name: "my_socket", persistent: false}. TCP client :

chrome.sockets.tcp.create(
  properties?: SocketProperties,
  callback: (createInfo: CreateInfo) => void,
)
TCP server :
chrome.sockets.tcpServer.create(
  properties?: SocketProperties,
  callback: (createInfo: CreateInfo) => void,
)
Once the socket is created, the passed callback is called with CreateInfo as parameter. This parameter is an object with contains socketId as a key. This socketId uniquely identifies the newly created socket.

Connect

Using the socketId created in previous step we can connect to remote machine with peerAddress & peerPort.

chrome.sockets.tcp.connect(
  socketId: number,
  peerAddress: string,
  peerPort: number,
  callback: function,
)
The callback is to signal that socket is now connected to the remote machine at provided address. This callback is called with a number parameter indicating success/error.

Send

If the created socket is the TCP server, we can send the data to desired remote machine.

chrome.sockets.tcp.send(
  socketId: number,
  data: ArrayBuffer,
  callback: function,
)
And to get notified of send acknowledgement, we also have a callback function which is called with parameter, SendInfo.

onReceive/onReceiveError Events

These are the events when any data arrives at the connected socket. These events are available on both TCP client and server.
onReceive event raised when data has been received for a given socket.
onReceiveError event raised when a network error occured while the runtime was waiting for data on the socket address and port. Once this event is raised, the socket is set to paused and no more onReceive events are raised for this socket.

onReceive/onReceiveError Event Listeners

To use onReceive/onReceiveError events, first we need to register it. Below are the way to register them. onReceiveListener

chrome.sockets.tcp.onReceiveError.addListener(
  callback: function,
)
The callback of this event is called with ReceiveInfo object which contains the data & the socketId. onReceiveErrorListener
chrome.sockets.tcp.onReceive.addListener(
  callback: function,
)
The callback of this event is called with ReceiveInfo object which contains the resultCode & the socketId.

Disconnect

This is also present on both TCP client and server. This method disconnects the socket from the remote machine. Still the socket is not destroyed yet. We can re-use this socket for another connection. TCP client :

chrome.sockets.tcp.disconnect(
  socketId: number,
  callback?: function,
)
TCP server :
chrome.sockets.tcpServer.disconnect(
  socketId: number,
  callback?: function,
)
The callback is called with zero parameters.

Close

This is the final stage in any socket's lifetime. This methos does two jobs - disconnect & destroys the socket. TCP client :

chrome.sockets.tcp.close(
  socketId: number,
  callback?: function,
)
TCP server :
chrome.sockets.tcpServer.close(
  socketId: number,
  callback?: function,
)
The callback is called with zero parameters.


Links & References

  1. https://www.lifesize.com/en/blog/tcp-vs-udp/
  2. https://www.w3.org/TR/tcp-udp-sockets
  3. https://developer.chrome.com/docs/extensions/reference/sockets_tcp/
  4. http://sgdev-blog.blogspot.com/2014/01/maximum-concurrent-connection-to-same.html

About Author

author
Lakshit Nagar (A full stack enthusiast)
Principle Software Developer
@Oracle India (Ex-ThoughtWorker, IIT Kanpur Alumni)

I love to shape my ideas into a reality. You can find me either working on a project or having a beer with my close friend. :-)

Connect: