了解 WebSocket

2024-01-20

我的理解是,一个socket对应一个网络标识符、端口和TCP标识符。 [1]

操作系统使进程能够与端口关联(IIUC 是使进程在网络上可针对入站数据进行寻址的一种方式)。

因此,WebSocket 服务器通常会与众所周知的用于接受和理解升级请求的 HTTP 的端口(如 443)相关联,然后使用 TCP 标识符来启用多个网络套接字,以便为单个服务器进程和单个端口同时打开。

请有人确认或更正我的理解吗?

[1] “提供唯一的名称 每个 TCP,我们连接一个 NETWORK 标识符和一个 TCP 标识符 使用端口名称来创建唯一的 SOCKET 名称 贯穿所有连接在一起的网络。” https://www.rfc-editor.org/rfc/rfc675 https://www.rfc-editor.org/rfc/rfc675


当客户端在给定端口上连接到服务器时,客户端连接来自 IP 地址和客户端端口号。客户端端口号由客户端自动生成,并且对于该客户端来说是唯一的。因此,您最终会得到四个可以建立联系的项目。

Server IP address  (well known to all clients)
Server port        (well known to all clients)
Client IP address  (unique for that client)
Client port        (dynamically unique for that client and that socket)

因此,正是这四项的组合构成了唯一的 TCP 连接。如果同一客户端对同一服务器和端口建立第二个连接,则该第二个连接将具有不同的客户端端口号(客户端建立的每个连接将被赋予不同的客户端端口号),因此上述四项的组合第二个客户端连接将有所不同,从而使其流量与客户端建立的第一个连接完全分开。

因此,TCP 套接字是上述四项的独特组合。要了解如何使用它,让我们看看一些流量是如何流动的。

客户端连接到服务器并创建 TCP 套接字来表示该连接后,客户端会发送数据包。该数据包是从客户端 IP 地址和该特定套接字正在使用的唯一客户端端口号发送的。当服务器在自己的端口号上接收到该数据包时,它可以看到该数据包来自客户端 IP 地址和该特定客户端端口号。它可以使用这些项目在其表中查找并查看该流量与哪个 TCP 套接字关联,并触发该特定套接字的事件。这将该客户端的流量与所有其他当前连接的套接字分开(无论它们是来自同一客户端的其他连接还是来自其他客户端的连接)。

现在,服务器想要向该客户端发送响应。数据包被发送到客户端的 IP 地址和客户端端口号。客户端 TCP 堆栈执行相同的操作。它从服务器 IP/端口接收数据包并发送到特定的客户端端口号,然后将该数据包与客户端上适当的 TCP 套接字相关联,以便它可以在正确的套接字上触发事件。

即使许多客户端可能连接到相同的服务器 IP 和端口,所有流量都可以通过这种方式唯一地与适当的客户端或服务器 TCP 套接字关联。客户端 IP/端口的唯一性允许两端知道给定数据包属于哪个套接字。


webSocket 连接以 HTTP 连接(这是运行 HTTP 协议的 TCP 套接字)开始。该初始 HTTP 请求包含一个“升级”标头,请求服务器将协议从 HTTP 升级到 webSocket。如果服务器同意升级,则返回响应,表明协议将更改为webSocket协议。 TCP 套接字保持不变,但双方都同意他们现在将使用 webSocket 协议而不是 HTTP 协议。因此,一旦连接,您就拥有了一个 TCP 套接字,双方都在使用 webSocket 协议。此 TCP 连接使用上述相同的逻辑来保持与同一服务器的其他 TCP 连接的唯一性。

通过这种方式,您可以在单个端口上拥有一个同时适用于 HTTP 连接和 webSocket 连接的服务器。到该服务器的所有连接都以 HTTP 连接开始,但在双方同意更改协议后,有些连接会转换为 webSocket 连接。保留 HTTP 连接的 HTTP 连接将是典型的请求/响应,然后套接字将被关闭。 “升级”到 webSocket 协议的 HTTP 连接将在 webSocket 会话期间保持打开状态(可以长期存在)。您可以拥有许多并发打开的 webSocket 连接,这些连接彼此不同,而新的 HTTP 连接均由同一台服务器定期提供服务。上面的 TCP 逻辑用于跟踪哪些数据包发往/来自同一服务器/端口属于哪个连接。


仅供参考,您可能听说过 NAT(网络地址转换)。这通常用于允许专用网络(如家庭或公司网络)连接到公共网络(如互联网)。通过 NAT,服务器可能会将多个客户端视为具有相同的客户端 IP 地址,即使它们是专用网络上物理上不同的计算机。使用NAT,多台计算机通过公共IP地址进行路由,但NAT仍然保证客户端IP地址和客户端端口号仍然是唯一的组合,因此上述方案仍然有效。使用 NAT 时,发往特定客户端的传入数据包将到达共享 IP 地址。然后,IP/端口被转换为专用网络上的实际客户端 IP 地址和端口号,然后数据包被转发到该设备。服务器通常不知道这种转换和数据包转发。由于 NAT 服务器仍然保持客户端 IP/客户端端口组合的唯一性,因此即使看起来许多客户端共享一个公共 IP 地址,服务器的逻辑仍然可以正常工作。请注意,家庭网络路由通常配置为使用 NAT,因为家庭网络上的所有计算机在访问互联网时都会“共享”路由器拥有的一个公共 IP 地址。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 WebSocket 的相关文章

  • Flutter Websockets MacOS:相同的代码可以在调试模式下工作,但不能在发布模式下工作:“(操作系统错误:提供了节点名或服务名..)”

    Summary 我有一个在 Flutter 中使用 WebSockets 的程序 该程序在debug模式 但运行相同exact代码在release模式会导致错误 Context Flutter 文档告诉我们如何使用 WebSocket ht
  • java.net.SocketException:无效参数:与 BungeeCord 连接

    我编写了一个使用 gRPC 连接到服务器的 Java 依赖项 在我的 spigot 插件和普通 java 项目中使用此依赖关系工作正常 但在 BungeeCord 插件中使用它会产生以下异常 Caused by io grpc netty
  • 同步 I/O 是否会使线程繁忙?

    假设我正在同步 I O 套接字上执行 I O 该套接字已准备好read or write手术 这意味着调用线程不会在操作上被阻塞 无论非阻塞 SOCK NONBLOCK 套接字的阻塞性质 但以下事情我不清楚 实际转移何时发生 当套接字标记为
  • 序列化是通过套接字发送数据的最佳选择吗?

    有人告诉我 序列化不是通过套接字发送数据的最佳方法 但他们说他们在一本书上读过一次 并且不确定更好的方法 因为他们以前没有真正做过网络 那么序列化是最好的方法还是有更好的方法 如果这有很大的不同的话 这也是一个游戏 通过搜索有关通过它发送对
  • 通过 PHP 连接到 socket.io(nodejs)

    我需要通过 php 连接到 websocket 发送数据并立即断开连接 无需等待套接字的响应 我用了大象io http elephant io 但更新库后不起作用 请告诉我如何通过 PHP 连接到 websocket 我也遇到了这个问题 学
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • C++套接字256字节缓冲区

    我正在尝试在 C 中使用一些套接字网络编程 我正在尝试发送文本 Hello World 使用 C send 函数发送到服务器 首先 我将缓冲区的大小设置为 13 因为 Hello World 总共是 12 个字符 必须比字符数多 1 个 如
  • 通过 Telnet 运行应用程序

    我需要创建一个 BAT 文件来通过 telnet 运行应用程序 但据我所知 在 DOS 上无法执行此操作 Telnet 不允许在连接的瞬间向远程计算机发送任何命令 并且 BAT 文件中的每个后续命令只有在 telnet 停止后才会执行 这段
  • Socket.io 400(错误请求)

    我的服务器上有这段代码 var express require express var routes require routes var user require routes user var http require http var
  • 通过套接字发送动态数组(在记录内)?

    我正在尝试直接使用 SendBuf 将记录从服务器传输到客户端 但是 该记录有一个动态数组的成员 并且我在某处 在 SOF 中 读到 发送记录时 成员必须是静态的 固定长度 但问题是 我无法确定如何我会 将来 发送许多论点 我怎么解决这个问
  • 中断 Select 以添加另一个要在 Python 中监视的套接字

    我正在 Windows XP 应用程序中使用 TCP 实现点对点 IPC 我正在使用select and socketPython 2 6 6 中的模块 我有三个 TCP 线程 一个读取线程通常会阻塞select 一个通常等待事件的写入线程
  • 安装 Python 3.5 包“socket”pycharm 时出错

    仅使用 PyCharm 或命令提示符无法安装此软件包 Collecting socket Using cached socket 0 5 tar gz Complete output from command python setup py
  • 什么是 SO_SNDBUF 和 SO_RCVBUF

    你能解释一下到底是什么吗SO SNDBUF and SO RCVBUF选项 好的 出于某种原因 操作系统缓冲传出 传入数据 但我想澄清这个主题 他们的角色 通 常 是什么 它们是每个套接字的缓冲区吗 传输层的缓冲区 例如 TCP 缓冲区 和
  • 在请求中设置端口

    我正在尝试利用cgminer使用 Python 的 API 我对利用requests图书馆 我了解如何做基本的事情requests but cgminer想要更具体一点 我想缩小 import socket import json sock
  • 使用 HTML5 或 Javascript 的 P2P 视频会议

    我正在尝试使用 html5 和 javascript 构建视频会议 直到现在我能够流式传输我的相机捕获并将其显示在画布上 这是代码
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • Java 服务器-客户端 readLine() 方法

    我有一个客户端类和一个服务器类 如果客户端向服务器发送消息 服务器会将响应发送回客户端 然后客户端将打印它收到的所有消息 例如 如果客户端向服务器发送 A 则服务器将向客户端发送响应 1111 所以我在客户端类中使用 readLine 从服
  • Python 无法使用套接字绑定我的外部/公共 IP 地址,给出错误但是当使用本地 IP 地址时,错误不会显示

    这是出现主要错误的代码 与我的本地 IP 的绑定将起作用 s bind 192 168 1 4 port 与我的公共 IP 的绑定失败并出现以下错误 s bind 99 99 99 99 port WinError 10049 请求的地址在
  • SQL Server“未找到网络路径”在不同环境中随机且不频繁地发生

    类似 如果不是同一个问题 随机遇到网络路径未找到异常 https stackoverflow com questions 38696448 network path not found exception encountered rando
  • Mac + Ruby:无法访问 Socket 的 ioctl?怎么修?

    一天中的好时光 红宝石代码 def hw address iface sock Socket new Socket AF INET Socket SOCK DGRAM 0 buf iface pack a16h16 sock ioctl S

随机推荐

  • 无法通过 GET 请求发送具有此动词类型的内容正文

    我当前正在通过 WebApi 接收请求 并尝试将其重新发送到另一个站点 目标是接收请求 例如 http localhost 9999 q 测试 http localhost 9999 q test 然后将其转发到真实站点 对于我的测试 我设
  • 如何在android中将字节数组(.h264格式)解码为视频?

    在我的应用程序中 我必须将字节数组 即 h264 格式 解码为视频和来自直播的字节数组 代码如下 static final int VIDEO BUF SIZE 100000 static final int FRAME INFO SIZE
  • Jupyter 笔记本内存管理

    我目前正在 kaggle 中开发 jupyter 笔记本 在我的 numpy 数组上执行所需的转换后 我将其腌制以便可以将其存储在磁盘上 我这样做的原因是为了释放大数组消耗的内存 pickle 阵列后消耗的内存约为 8 7 GB 我决定运行
  • 游戏框架架构——视图组件还是MVC?

    我正在尝试为我的游戏构建一个非常轻量级的可重用框架 而不是每次开始游戏时都从头开始 我有一个组件驱动的架构 例如实体由Position组件 Health组件 Ai组件等组成 我最大的问题是我的模型组成视图组件允许模型有多个视图 或者是否使用
  • 如何在 R 中绘制度分布

    我想知道绘制度分布的脚本的输出是否正确 所以脚本是 其中带有我所有顶点度数的向量存储在 x 中 x is x 1 7 9 8 5 6 2 8 9 7 5 2 4 6 9 2 6 10 8 x 是某个网络顶点的度数 例如顶点 1 的度数为 7
  • React Native 适用于互联网带宽较低的小尺寸 apk

    我计划为互联网带宽较低的新兴市场开发一款应用程序 该应用程序严重需要互联网连接才能运行 我需要这个应用程序有一个小的 apk 大小 不超过10mb 并继续努力3G网络 根据我的研究 如果我删除x86来自 React Native 的 JS
  • 有没有好的 PostgreSQL linux 客户端? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我对 PostgreSQL 没有一个好的 Linux GUI 管理和开发工具感到沮丧 与仅限 Windo
  • 将子字符串包裹在 标签中,而无需在替换时创建嵌套标签

    我有一个单词数组 用于突出显示字符串中的单词 但是有些单词可能会作为短语的一部分出现 因此我希望该短语优先于突出显示中的单个单词 例如 seo apple apple tree orchard description In my orcha
  • 在 mySQL 中存储 javascript Date()

    我目前有一个 javascript 变量 它记录当前日期和时间 如下所示 var time of call time of call new Date 我需要将它存储在 MySQL 数据库中 当我尝试上传它时 该列仅显示为空白 但我不确定我
  • Node.js - 每个 Express 请求的域,在另一个域内

    Node js 中的错误处理啊 我正在尝试布局一个像这样的基本 Node 应用程序 集群 gt Worker gt 服务器域 gt 快速请求域 因此 如果由于有人在登录表单上拼错了自己的名字而将错误抛出到调用堆栈的 18 层深处 则整个服务
  • 在线程中更改Python“请求”模块的连接池大小

    编辑 也许我对这个错误的含义是错误的 这是否表明我的客户端的连接池已满 或者服务器的连接池已满 这是我的客户端收到的错误 我正在尝试制作大量http使用 python 并发请求threading and requests模块 我在日志中看到
  • Linux 上的 C++ 开发 Code::Blocks、EMACS 或 GVIM [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在多个项目之间共享声明式管道

    我在不同的存储库中有很多项目 它们共享相同的基本 CI 工作流程 我可以轻松地将其表达为声明式管道 pipeline agent any options buildDiscarder logRotator numToKeepStr 20 s
  • 使用相同关键字并条件 Django 查询

    我有一个带有发布模型和标签模型的 Django 应用程序 每份出版物都有一个或多个与其关联的标签 我想使用一组两个标签查询数据库 并且仅返回同时具有这两个标签的出版物 尽管我确信它很容易获得 但我似乎找不到它的语法 我想我没有使用正确的语言
  • 为什么我的应用程序没有绘制任何东西?

    我对 C 一般编程 非常陌生 阅读了 3 周的经验 从 html css 和 javascript 开始 现在开始使用 C 我正在尝试以 Windows 形式制作自己的简单 绘画 应用程序 但我遇到了一个问题 只是无法解决它 无论我阅读或遵
  • 如何在 Javascript 中替换字符串中的撇号?

    给定一个 Javascript 中的字符串 例如 var str this s kelly 我想用另一个字符替换撇号 这是我到目前为止所尝试过的 str replace quot A str replace A 这些都不起作用 我该怎么做
  • 追踪有用信息

    这里聪明的程序员如何跟踪他们在多年的经验中获得的方便的编程技巧和有用的信息 诸如有用的编译器参数 IDE 快捷方式 巧妙的代码片段等 当我查找一两年前我曾经知道的东西时 我有时会感到沮丧 我最喜欢的 IE 可能代表了 20 世纪 90 年代
  • Linq 多个 OR 与列表

    我目前正在开发一个使用 LINQ 的 C 项目 我想知道是否可以使用 Linq 创建一个 多个 OR 子句 并将列表作为 where 的条目 我的意思是这样的 var listofId var sqlQuery from T in myta
  • 加载共享库时出错:?:无法打开共享对象文件:没有这样的文件或目录

    我正在尝试诊断 并修复 位于多个组件边界上的问题 非常感谢任何有关如何获取更多信息或彻底解决问题的见解 我有一个应用程序 它作为 C 程序启动 可以启动 Java 程序 然后可以以递归方式启动相同的 C 程序 它已经在 Linux 和 Cy
  • 了解 WebSocket

    我的理解是 一个socket对应一个网络标识符 端口和TCP标识符 1 操作系统使进程能够与端口关联 IIUC 是使进程在网络上可针对入站数据进行寻址的一种方式 因此 WebSocket 服务器通常会与众所周知的用于接受和理解升级请求的 H