TCP套接字和Web套接字的区别,再次解释

219

1
我认为你从维基百科摘取的那句话有点误导人。根据我刚才从你提供的链接中所读到的,WebSockets只是用于非HTTP流量的HTTP TCP连接。也就是说,你可以在与服务器的TCP连接上协商使用它的80端口来进行VPN类型的流量传输或其他操作。因此,WebSocket只是一个非HTTP的HTTP套接字?这只是我的猜测...不确定维基百科摘录中所说的“消息”是否指的是字节。 - 0xhughes
7
消息:给我一个 JSON 数据包,再给我另一个 JSON 数据包。完整的消息。字节流:给我 n 个字节,我会回复 100 Continue,然后你再给我下一个 n 个字节。重复此过程,直到没有更多的字节。这些是在服务器上重新组装的不完整消息。用于流媒体和分块。 - Sinaesthetic
2个回答

295
当你使用普通的TCP套接字从缓冲区发送字节时,发送函数会返回已发送的缓冲区字节数。如果是非阻塞套接字或非阻塞发送,则发送的字节数可能小于缓冲区的大小。如果是阻塞套接字或阻塞发送,则返回的数字将与缓冲区的大小匹配,但调用可能会阻塞。在WebSocket中,传递给send方法的数据始终作为整个“消息”发送或根本不发送。此外,浏览器WebSocket实现不会在发送调用上阻塞。
但在接收方面,有更重要的差异。当接收方在TCP套接字上执行recv(或read)时,不能保证返回的字节数对应于发送端的单个send(或write)。它可能相同,可能较少(或为零),甚至可能更多(在这种情况下,将接收来自多个send / write的字节)。对于WebSockets,消息的接收者是事件驱动的(通常注册消息处理程序例程),并且事件中的数据始终是另一侧发送的完整消息。
请注意,您可以使用TCP套接字进行基于消息的通信,但需要一些额外的层/封装,以添加帧/消息边界数据到消息中,以便可以从这些片段重新组装原始消息。事实上,WebSockets基于普通的TCP套接字构建,并使用包含每个帧大小并指示哪些帧属于消息的帧标头。WebSocket API将TCP数据块重新组合成帧,这些帧在调用消息事件处理程序之前被组装成消息。

8
那么,WebSocket只是普通TCP套接字和Web浏览器之间的额外层吗? - Marc Casavant
26
你的问题似乎暗示了WebSockets没有必要存在。我认为可以反过来看,WebSockets是对TCP的封装,将TCP类似的功能和性能带到浏览器中,而不需要使用插件,并且不会放弃艰苦奋斗获得的浏览器安全最佳实践(如CORS)。在握手之后,额外层的开销非常轻(小帧仅需2字节头)。 - kanaka
5
这是对实际政策的相当错误的陈述。你所谓的情况是荒谬的。实际上,政策只是说:“专家编辑应该注意到可能存在潜在利益冲突的情况,如果编辑与专家自己的研究、著作或发现有关的文章。” - user207421
2
@EJP 是的,这很荒谬。这是我的经验,政策在实践中如何展开。 "政策警察"会过来删除有价值的信息-正如实际读者所承认的那样。请参见http://en.wikipedia.org/wiki/Talk:Comparison_of_WebSocket_implementations和http://en.wikipedia.org/wiki/User_talk:Oberstet#Conflict_of_Interest_on_WebSockets_comparison。 - oberstet
1
可以说WebSockets是使用浏览器的“RAW TCP/IP连接”的最标准化方法吗?在帧内,它确实等待完整的消息接收。因此它不是真正的流,但不应该是一个问题(实际上非常有用)。检查基于WebSockets的游戏,它们在大多数浏览器中工作,并且实际上非常响应快。 - Paul
显示剩余2条评论

205

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

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

在幕后,WebSocket将TCP帧重构为一致的包/消息。全双工通道由服务器用于异步地向客户端推送更新: 通道处于开放状态,客户端可以调用任何未来/回调/承诺来管理任何异步WebSocket接收到的消息。

简而言之,WebSocket是一种高级协议(就像HTTP本身),建立在TCP之上(可靠的传输层,在每帧基础上),使得可以通过JS客户端构建有效的实时应用程序(以前使用Comet和长轮询技术从服务器获取更新,在WebSockets实现之前。请参见Stackoverflow帖子: WebSockets和长轮询用于回合制游戏服务器的区别)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接