草庐IT

sockets - 了解WebSockets

coder 2023-09-17 原文

我的理解是,套接字对应于网络标识符,端口和TCP标识符。 [1]

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

因此,WebSocket服务器通常将与一个端口相关联,该端口因接受和理解升级请求的HTTP而闻名(例如443),然后使用TCP标识符使单个服务器进程和单个端口同时打开多个网络套接字。 。

请有人可以确认或纠正我的理解吗?

[1]“在
每个TCP,我们会连接一个NETWORK标识符和一个TCP标识符
使用端口名称来创建SOCKET名称,该名称将是唯一的
在连接在一起的所有网络中。” https://tools.ietf.org/html/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协议(protocol)的TCP套接字)开始。该初始HTTP请求包含一个“升级” header ,请求服务器将协议(protocol)从HTTP升级到webSocket。如果服务器同意升级,则它将返回响应,指示该协议(protocol)将更改为webSocket协议(protocol)。 TCP套接字保持不变,但是双方都同意,他们现在将使用webSocket协议(protocol)而不是HTTP协议(protocol)。因此,一旦连接,您便有了一个TCP套接字,双方都在说webSocket协议(protocol)。此TCP连接使用上述相同的逻辑,以保持与其他TCP连接到同一服务器的唯一性。

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

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

关于sockets - 了解WebSockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43817850/

有关sockets - 了解WebSockets的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  3. ruby-on-rails - 如何测试自己对 Ruby/ROR 的了解? - 2

    是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby​​和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T

  4. ruby-on-rails - 了解 "attribute_will_change!"方法 - 2

    我想覆盖store_accessor的getter。可以查到here.代码在这里:#Fileactiverecord/lib/active_record/store.rb,line74defstore_accessor(store_attribute,*keys)keys=keys.flatten_store_accessors_module.module_evaldokeys.eachdo|key|define_method("#{key}=")do|value|write_store_attribute(store_attribute,key,value)enddefine_met

  5. ruby - 我怎样才能更好地了解/了解更多关于 Ruby 的知识? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?

  6. ruby-on-rails - 正确了解 Rails 框架的最佳方式是什么? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我一直在Rails上做两个项目,它们运行良好,但在这个过程中重新发明了轮子,自来水(和热水)和止痛药,正如我随后了解到的那样,这些已经存在于框架中。那么基本上,正确了解框架中所有智能部分的最佳方法是什么,这将节省时间而不是自己构建已经实现的功能?从第1页开始阅读文档?是否有公开所有内容的特定示例应用程序?一个特定的开源项目?所有的rails交通?还是完全

  7. ruby - 了解 Ruby Enumerable#map(具有更复杂的 block ) - 2

    假设我有一个函数defodd_or_evennifn%2==0return:evenelsereturn:oddendend我有一个简单的可枚举数组simple=[1,2,3,4,5]然后我用我的函数在map中运行它,使用一个do-endblock:simple.mapdo|n|odd_or_even(n)end#=>[:odd,:even,:odd,:even,:odd]如果不首先定义函数,我怎么能做到这一点?例如,#doesnotworksimple.mapdo|n|ifn%2==0return:evenelsereturn:oddendend#Desiredresult:#=>[

  8. ruby - 了解 Ruby 中赋值和逻辑运算符的优先级 - 2

    在以下示例中,我无法理解Ruby运算符的优先级:x=1&&y=2由于&&的优先级高于=,我的理解是类似于+和*运算符:1+2*3+4解析为1+(2*3)+4它应该等于:x=(1&&y)=2但是,所有Ruby源代码(包括内部语法解析器Ripper)都将其解析为x=(1&&(y=2))为什么?编辑[08.01.2016]让我们关注一个子表达式:1&&y=2根据优先规则,我们应该尝试将其解析为:(1&&y)=2这没有意义,因为=需要特定的LHS(变量、常量、[]数组项等)。但是既然(1&&y)是一个正确的表达式,那么解析器应该如何处理呢?我试过咨询Ruby的parse.y,但它太像意大利面条

  9. ruby - 了解 ruby 奎因 - 2

    我在维基百科上找到了这个代码块,作为Ruby中quine(打印自身的程序)的示例。puts但是,我不明白它是如何工作的。特别是,我没有得到的是,当我删除最后一行时,出现此错误:syntaxerror,unexpected$end,expectingtSTRING_CONTENTortSTRING_DBEGortSTRING_DVARortSTRING_END这些行中发生了什么? 最佳答案 语法以here-document开始,通过Perl从UNIXshell借用-它基本上是一个多行字符串文字,从之后的行开始当一行以something

  10. 最近火热的“数字藏品”,你真的了解吗? - 2

    最近火热的“数字藏品”,你真正了解吗?其实有很多人会把数字藏品跟NFT混为一谈,但其实这两者还是有差别的。数字藏品并不等同于NFT数字藏品是什么?直观来看,它可能就是一张数字化照片或视频,甚至就只是一串数字。但它却是一件对应特定作品、艺术品生成的包含着大量数字信息且拥有唯一加密信息的可以买卖交易的收藏品。NFT则是指一种基于以太坊区块链的“非同质化代币”。它在百度百科里的释义是“用于表示数字资产(包括jpg和视频剪辑形式)的唯一加密货币令牌,可以买卖”。比如已被很多人认识的比特币就是NFT的一种。NFT在元宇宙中发挥的作用是巨大的,目前正是它在支撑着元宇宙中的经济体系。数字藏品其实也是NFT的

随机推荐