8

As I understand:

  • A port designates a program on the server.
  • When we say to share a port, it actually means to have the requests processed by the same program listening on that port.

The WebSocket handshake resembles the HTTP format, so it can be understood by the server program that handles HTTP protocol. So it's OK to send the handshake request to port 80.

But after the handshake, the WebSocket data format is totally different from HTTP format, how could it still be sent to port 80? Such as via URL like below:

ws://somehost:80/chat

How does it work out?

My guess:

Does the HTTP program see that the incoming request on port 80 cannot be handled as HTTP, and then it will pass it to WebSocket program to process it. If so, what if there's some other protocol that wants to share port 80, say WebSocket2, how could HTTP program know which protocol to pass on to if there's not a way to identify the protocol being used.

ADD 1

Based on jfriend00's reply, I draw the following diagram:

So WebSocket and HTTP traffic in the same browser are actually carried out through different socket connections. Though they both start by connecting to server's port 80.

I think if the word WebSocket doesn't contain a socket in it, it will be easier to understand it as just another application level protocol over TCP protocol.

enter image description here

ADD 2

I refined the above diagram to below based on jfriend00's further comments. What I want to show is how WebSocket communication and HTTP communication to the same server coexist in a browser.

enter image description here

ADD 3

After reading this thread, I recalled that the server port doesn't change when server accept a connection: Does the port change when a TCP connection is accepted by a server?

So the diagram should be like this:

The TCP connection for HTTP and the TCP connection for WebSocket should be using different client ports.

enter image description here

Community
  • 1
  • 1
smwikipedia
  • 61,609
  • 92
  • 309
  • 482

2 Answers2

15

When a server listens on a given port, it is listening for incoming connections. When a new incoming connection arrives, it is given its own socket to run on. That socket provides the connection between the two endpoints. From then on, that socket runs completely independently from all other sockets that might also be connected.

So, one incoming http request can specify the "upgrade" header and get upgraded to webSocket and then both ends agree to talk the webSocket protocol from then on. Meanwhile, other incoming http requests without that upgrade header are treated only as normal http requests.

In case you don't quite understand how the webSocket protocol works, you can get a full look at how it connects here.

Here are the main steps:

  1. The client requesting a webSocket connection, sends an HTTP request to the server on port 80.
  2. That HTTP request is a perfectly legal HTTP request, but it has a header included on it Upgrade: websocket.
  3. If the server supports the webSocket protocol, then it responds with a legal HTTP response with a 101 status code that includes a header Connection: Upgrade.
  4. At that point, both sides then switch protocols to the webSocket protocol and all future communication on that socket is done using the data format for the webSocket frame.

Any other incoming HTTP requests that do not contain the upgrade request header are treated as normal HTTP requests.

Does the HTTP program see that the incoming request on port 80 cannot be handled as HTTP, and then it will pass it to WebSocket program to process it.

No, the first request IS a legal HTTP request (just with a special header in it) and the response sent back is a legal HTTP response. But, after that response, both sides switch protocols to webSocket. So a custom header is used to tell the web server that this incoming HTTP request is meant to be the first step in establishing a webSocket connection.

If so, what if there's some other protocol that wants to share port 80, say WebSocket2, how could HTTP program know which protocol to pass on to if there's not a way to identify the protocol being used.

This upgrade mechanism could be used to support other protocols too by just specifying a different protocol name Upgrade: someOtherProtocol though I'm not aware of any others that have been standardized.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    @smwikipedia - I don't quite understand what you're trying to show in the diagram. A webSocket connection is its own socket. It starts out as a TCP socket speaking the HTTP protocol. After parsing the incoming upgrade header and returning the 101 status, it becomes the same TCP socket speaking the webSocket protocol. Subsequent incoming HTTP connections will be there own TCP sockets and can decide on their own what protocol they will speak. – jfriend00 Nov 11 '15 at 06:27
  • 1
    @smwikipedia - Port 80 is kind of like the central phone number of a large corporation. Lots of incoming calls can arrive at that number, but as each one is connected, each becomes it's own separate call and the two people on each end of each call can then agree on whatever language they want to speak. Further each incoming call is completely separate from all the other calls - they each have nothing to with one another except that they all have to initially speak to the receptionist using one common language. After that, they can be handed somewhere and agree to whatever language they want. – jfriend00 Nov 11 '15 at 06:29
  • 2
    @smwikipedia - one thing that seems wrong in the diagram is that as soon as the whole process starts with the original HTTP connection, the underlying TCP socket connection already exists. There's no "new" socket created for webSocket. The socket for a given connection already exists and you just have both sides agreeing to speak the webSocket protocol instead of the HTTP protocol. It would be like you calling your mom's house, answering the phone in English and then both agreeing in English that you were going to switch to speaking Spanish. It's the same phone connection, different language. – jfriend00 Nov 11 '15 at 06:31
  • What I want to show is how `WebSocket` communication coexists with `HTTP` communication in a browser. When I construct a WebSocket connection, I usually use a URL with `the same port` as I visit web page, such as `ws://myserver:80`. (`step (1)` in my diagram). Then server creates another dedicated socket for real communication (`step (2)`). Depending on whether `upgrade` header exists, this new socket will speak WebSocket or not. And the following communication carries out accordingly (`step (3)`). – smwikipedia Nov 11 '15 at 06:33
  • 1
    @smwikipedia - All webSocket connections start by making a TCP socket connection to the server and sending an HTTP formatted message over that TCP socket. Then, after the server processes the upgrade header, both sides agree to take that EXACT socket and switch the protocol to the webSocket protocol. No new socket is created for the webSocket. The same one that already exists (that they were just talking HTTP over) is used. There is no "new" socket to speak webSocket. The socket is a TCP level thing and it existed first before there was any protocol. – jfriend00 Nov 11 '15 at 06:36
  • Agree. I draw `step (1)` because I want to differentiate the server listening port `s_port_0` (which is usually 80) from the port actually used for communication, `s_port_1` and `s_port_2`. Yes, it's not very clear. I kind of mix together the server port change and the WebSocket/HTTP protocol change. Let me see how to draw a better one. – smwikipedia Nov 11 '15 at 06:47
  • I refined the diagram. – smwikipedia Nov 11 '15 at 06:59
  • Thank you so much, Mr. jfriend00. I was doing research on the WebSockets and was looking for something similar. The steps and the way you answered is pretty much excellent. Your answer helped me a lot. Too much respect for you sir. Thank you so much. –  Oct 17 '18 at 20:01
0

Because the browser use a new port to connect and send/receive messages to/from the server.

Stephen.W
  • 1,649
  • 13
  • 14