TCP 套接字和 web 套接字的区别

为了尽可能地理解 TCP 套接字和 websocket 之间的区别,我已经在这些问题中找到了很多有用的信息:

等等……

在我的调查中,我在维基百科上看了这句话:

Websocket与TCP的不同之处在于它启用消息流而不是字节流

我不太清楚这到底是什么意思。你的解读是什么?

158051 次浏览

当您使用普通TCP套接字从缓冲区发送字节时,send函数返回发送的缓冲区字节数。如果它是非阻塞套接字或非阻塞发送,则发送的字节数可能小于缓冲区的大小。如果它是一个阻塞套接字或阻塞发送,那么返回的数字将匹配缓冲区的大小,但调用可能阻塞。使用WebSockets,传递给send方法的数据总是要么作为一个完整的“消息”发送,要么根本不发送。另外,浏览器WebSocket实现不会阻塞发送调用。

但在接受方面有更重要的区别。当接收方在TCP套接字上执行recv(或read)操作时,不能保证返回的字节数对应于发送方的单个发送(或写)。它可能是相同的,它可能更少(或零),甚至可能更多(在这种情况下,来自多个发送/写入的字节被接收)。使用WebSockets,消息的接收者是事件驱动的(您通常注册一个消息处理程序例程),事件中的数据总是另一方发送的整个消息。

注意,您可以使用TCP套接字进行基于消息的通信,但是需要一些额外的层/封装,即向消息中添加帧/消息边界数据,以便原始消息可以从各个片段重新组装起来。事实上,WebSockets是建立在正常的TCP套接字之上的,它使用包含每个帧大小的帧报头,并指出哪些帧是消息的一部分。WebSocket API在每条消息调用一次消息事件处理程序之前,将TCP数据块重新组装成帧,然后再组装成消息。

WebSocket基本上是一个应用协议(参考ISO/OSI网络栈),面向消息,其中利用TCP协议作为传输层。

WebSocket协议背后的思想包括重用客户端和服务器之间已建立的TCP连接。在HTTP握手之后,客户端和服务器端通过交换WebSocket信封开始讲WebSocket协议。HTTP握手用于克服客户端和提供某些服务的服务器之间的任何障碍(例如防火墙)(通常80端口可以从任何地方被任何人访问)。客户端和服务器可以在任何时候切换HTTP,使用相同的TCP连接(永远不会释放)。

在幕后WebSocket在一致的信封/消息中重新构建TCP帧。全双工通道被推送服务器以异步方式更新到客户端:通道是打开的,客户端可以调用任何期货/回调/承诺来管理任何异步WebSocket接收到的消息。

简单地说,WebSocket是一个建立在TCP(可靠的传输层,每帧为基础)上的高级协议(就像HTTP本身一样),这使得用JS客户端构建有效的实时应用程序成为可能(以前Comet和长轮询技术在WebSocket实现之前从服务器使用获取更新)。参见Stackoverflow post: 基于回合的游戏服务器的websocket和长轮询之间的区别)。