为什么WebSocket可以“握手后"与HTTP共享80端口? [英] Why WebSocket can share the 80 port with HTTP "after the handshake"?

查看:73
本文介绍了为什么WebSocket可以“握手后"与HTTP共享80端口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知:

  • 端口指定服务器上的程序.
  • 当我们说共享端口时,它实际上意味着让同一程序处理请求,侦听该端口.

WebSocket 握手类似于 HTTP 格式,因此处理 HTTP 协议的服务器程序可以理解它.所以发送握手请求到port 80就可以了.

但是握手后,WebSocket的数据格式和HTTP格式完全不同,怎么还会发送到80端口呢?例如通过如下网址:

ws://somehost:80/chat

效果如何?

我的猜测:

HTTP 程序是否看到 80 端口的传入请求不能作为 HTTP 处理,然后将其传递给 WebSocket 程序进行处理.如果是这样,如果有其他一些协议想要共享端口 80,比如 WebSocket2,如果没有识别正在使用的协议的方法,HTTP 程序如何知道要传递给哪个协议.

加 1

根据jfriend00的回复,我画了下图:

所以WebSocket和HTTP在同一个浏览器中的流量实际上是通过不同的socket连接进行的.尽管它们都是从连接到服务器的端口 80 开始的.

我认为,如果 WebSocket 这个词中不包含 socket,那么将它理解为 TCP 协议之上的另一种应用级协议会更容易.

添加 2

我根据 jfriend00 的进一步评论将上图细化为下图.我想展示的是 WebSocket 通信和 HTTP 通信如何在浏览器中共存.

添加 3

阅读这个帖子后,我想起服务器接受连接时服务器端口不会改变:

解决方案

当服务器侦听给定端口时,它正在侦听传入连接.当新的传入连接到达时,它会被赋予自己的套接字来运行.该套接字提供了两个端点之间的连接.从那时起,该套接字完全独立于所有其他可能连接的套接字运行.

因此,一个传入的 http 请求可以指定升级"标头并升级到 webSocket,然后两端同意从那时起讨论 webSocket 协议.同时,其他没有该升级标头的传入 http 请求仅被视为正常的 http 请求.

如果您不太了解 webSocket 协议的工作原理,您可以全面了解它是如何连接的 此处.

以下是主要步骤:

  1. 客户端请求 webSocket 连接,在端口 80 上向服务器发送 HTTP 请求.
  2. 该 HTTP 请求是一个完全合法的 HTTP 请求,但其中包含一个标头 Upgrade: websocket.
  3. 如果服务器支持 webSocket 协议,那么它会用一个带有 101 状态代码的合法 HTTP 响应来响应,其中包含一个标头 Connection: Upgrade.
  4. 此时,双方将协议切换到 webSocket 协议,并且该套接字上的所有未来通信都使用 webSocket 帧的数据格式完成.

任何其他不包含 upgrade 请求标头的传入 HTTP 请求都被视为正常的 HTTP 请求.

<块引用>

HTTP 程序是否看到 80 端口的传入请求无法作为 HTTP 处理,然后将其传递给 WebSocket 程序以处理它.

不,第一个请求是合法的 HTTP 请求(只是在其中包含一个特殊的标头),返回的响应是合法的 HTTP 响应.但是,在该响应之后,双方将协议切换到 webSocket.因此,自定义标头用于告诉 Web 服务器此传入的 HTTP 请求是建立 webSocket 连接的第一步.

<块引用>

如果是这样,如果有其他协议想要共享端口怎么办80,说WebSocket2,HTTP程序怎么知道要通过哪个协议如果无法识别正在使用的协议,则继续.

这个 upgrade 机制也可以用于支持其他协议,只需指定不同的协议名称 Upgrade: someOtherProtocol 虽然我不知道其他任何协议标准化.

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.

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.

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.

解决方案

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.

这篇关于为什么WebSocket可以“握手后"与HTTP共享80端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆