为什么WebSocket可以在"握手后"与HTTP共享80端口?

smw*_*dia 4 html5 http websocket

我认为:

  • 端口指定服务器上的程序.
  • 当我们说to share a port,它实际上意味着to have the requests processed by the same program listening on that port.

WebSocket握手resemblesHTTP格式,因此can处理HTTP协议的服务器程序可以理解.所以发送握手请求是可以的port 80.

但是after the handshake,WebSocket数据格式与HTTP格式完全不同,它怎么还能发送到端口80?如下面的URL:

ws://somehost:80/chat

它是如何运作的?

我猜:

HTTP程序是否在端口80上看到传入的请求cannot be handled as HTTP,然后它将它传递给WebSocket程序来处理它.如果是这样,如果有一些其他协议想要共享端口80,比如WebSocket2,如果没有办法识别正在使用的协议,那么HTTP程序如何知道要传递哪个协议.

添加1

根据jfriend00回复,我绘制了下图:

因此,同一浏览器中的WebSocket和HTTP流量实际上是通过different套接字连接实现的.虽然他们都开始连接到服务器的端口80.

我认为如果WebSocket这个词中没有包含套接字,那么将它更容易理解为TCP协议上的另一个应用程序级协议.

在此输入图像描述

添加2

我根据jfriend00进一步的评论将上面的图表改进了下面.我想要展示的是WebSocket如何与coexist浏览器中的同一服务器进行通信和HTTP通信.

在此输入图像描述

添加3

读完这个帖子之后,我回想一下,当服务器接受连接时,服务器端口不会改变:当服务器接受TCP连接时,端口是否会改变?

所以图表应该是这样的:

HTTP的TCP连接和WebSocket的TCP连接应该使用不同的client ports.

在此输入图像描述

jfr*_*d00 10

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

因此,一个传入的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尽管我不知道任何已经标准化的其他协议.

  • @smwikipedia - 图中看似错误的一件事是,只要整个进程以原始HTTP连接开始,底层TCP套接字连接就已经存在.没有为webSocket创建的"新"套接字.给定连接的套接字已经存在,您只需要双方同意使用webSocket协议而不是HTTP协议.这就像你打电话给你妈妈的房子,用英语接听电话,然后双方用英语同意你将改用西班牙语.它是相同的电话连接,不同的语言. (2认同)