TCP 套接字是由特定 TCP 连接或侦听状态的上下文中的 IP 地址和端口定义的端点实例 。
端口是定义服务端点的虚拟化标识符 (与服务实例端点即会话标识符不同)。
TCP 套接字不是连接 ,它是特定连接的端点。
可以与服务端点建立并发连接 ,因为连接由其本地和远程端点标识,允许将流量路由到特定服务实例。
对于给定的地址 / 端口组合,只能有一个侦听器套接字 。
这是一个有趣的问题,迫使我重新审视一些我认为我内心深处知道的事情。您认为像 “socket” 这样的名称是不言自明的:显然选择它来唤起您插入网络电缆的端点的图像,具有强大的功能相似性。然而,在网络用语中,“插座” 这个词带来了太多的包袱,需要仔细的重新检查。
在最广泛的意义上,端口是入口或出口的点。虽然没有在网络环境中使用,但法语单词porte字面意思是门或网关 ,进一步强调了无论您运送数据还是大型钢制容器,港口都是运输终点的事实。
出于本讨论的目的,我将限制考虑 TCP-IP 网络的背景。 OSI 模型非常好,但从未完全实现,在高流量高压力条件下更不广泛部署。
IP 地址和端口的组合严格称为端点,有时称为套接字。此用法源自 RFC793,即原始 TCP 规范。
TCP 连接由两个端点(即套接字 )定义。
端点(套接字)由网络地址和端口标识符的组合定义。请注意,地址 / 端口不能完全识别套接字(稍后将详细介绍)。
端口的目的是区分给定网络地址上的多个端点。您可以说端口是虚拟化端点。此虚拟化可在单个网络接口上实现多个并发连接。
它是套接字对(由客户端 IP 地址,客户端端口号,服务器 IP 地址和服务器端口号组成的 4 元组),它指定唯一标识 Internet 中每个 TCP 连接的两个端点。 ( TCP-IP Illustrated Volume 1 ,W。Richard Stevens)
在大多数 C 派生语言中,使用 Socket 类实例上的方法建立和操作 TCP 连接。虽然通常在更高级别的抽象上操作(通常是 NetworkStream 类的实例),但这通常会暴露对套接字对象的引用。对于编码器,此套接字对象似乎表示连接,因为使用套接字对象的方法创建和操作连接。
在 C#中,首先要建立 TCP 连接(对现有的侦听器),然后创建一个TcpClient 。如果没有为TcpClient构造函数指定端点,则它使用默认值 - 以这种或那种方式定义本地端点。然后在您创建的实例上调用Connect方法。此方法需要一个描述另一个端点的参数。
这一切都有点令人困惑,让你相信套接字是一个连接,这是一个连接。在 Richard Dorman 提出这个问题之前,我一直在这种误解中努力工作。
经过大量的阅读和思考,我现在相信,使用带有两个参数LocalEndpoint和RemoteEndpoint的构造函数来创建类TcpConnection会更有意义。当本地端点可以接受默认值时,您可能支持单个参数RemoteEndpoint 。这在多宿主计算机上是不明确的,但是通过选择具有到远程端点的最短路由的接口,可以使用路由表来解决模糊性。
清晰度在其他方面也会得到加强。 IP 地址和端口的组合未标识套接字:
[...] TCP 使用包含本地和外部地址的所有四个值对传入段进行解复用:目标 IP 地址,目标端口号,源 IP 地址和源端口号。 TCP 无法通过仅查看目标端口来确定哪个进程获取传入的段。此外,[给定端口号] 的 [各种] 端点中唯一一个将接收传入连接请求的端点是处于监听状态的端点。 (p255, TCP-IP 插图第 1 卷 ,W。Richard Stevens)
正如您所看到的,网络服务不仅可能而且很可能具有多个具有相同地址 / 端口的套接字,但在特定地址 / 端口组合上只有一个侦听器套接字。典型的库实现提供了一个套接字类,其实例用于创建和管理连接。这是非常不幸的,因为它引起混乱并导致这两个概念的广泛混合。
Hagrawal 不相信我(见评论)所以这是一个真实的样本。我将 Web 浏览器连接到http://dilbert.com ,然后运行netstat -an -p tcp
。输出的最后六行包含两个例子,即地址和端口不足以唯一地标识套接字。 192.168.1.3(我的工作站)和 54.252.92.236:80 之间有两个不同的连接
TCP 192.168.1.3:63240 54.252.94.236:80 SYN_SENT
TCP 192.168.1.3:63241 54.252.94.236:80 SYN_SENT
TCP 192.168.1.3:63242 207.38.110.62:80 SYN_SENT
TCP 192.168.1.3:63243 207.38.110.62:80 SYN_SENT
TCP 192.168.1.3:64161 65.54.225.168:443 ESTABLISHED
由于套接字是连接的端点,因此有两个套接字,其地址 / 端口组合为207.38.110.62:80
,另外两个套接字具有地址 / 端口组合54.252.94.236:80
。
我认为 Hagrawal 的误解源于我非常谨慎地使用 “识别” 这个词。我的意思是 “完全,明确和唯一地识别”。在上面的示例中,有两个端点,其地址 / 端口组合为54.252.94.236:80
。如果只有地址和端口,则没有足够的信息来区分这些插槽。 识别套接字的信息不足。
RFC793 第 2.7 节第 2 段说
连接由末端的一对插座完全指定。本地套接字可以参与到不同外部套接字的许多连接。
从编程角度来看,套接字的这种定义是没有用的,因为它与套接字对象不同 ,套接字对象是特定连接的端点。对于程序员而言,这个问题的大多数观众都是程序员,这是一个至关重要的功能差异。
套接字由三件事组成:
端口是 1 到 65535 之间的数字,表示设备中的逻辑门。客户端和服务器之间的每个连接都需要唯一的套接字。
例如:
套接字表示两个网络应用程序之间的单个连接。这两个应用程序名义上运行在不同的计算机上,但套接字也可用于单个计算机上的进程间通信。应用程序可以创建多个套接字以便相互通信。套接字是双向的,这意味着连接的任何一端都能够发送和接收数据。因此,理论上可以在 2 个以上的 OSI 模型的任何级别创建套接字。程序员经常在网络编程中使用套接字,尽管是间接的。像 Winsock 这样的编程库隐藏了许多套接字编程的低级细节。自 20 世纪 80 年代初以来,插座已广泛使用。
端口表示网络通信的端点或 “通道”。端口号允许同一台计算机上的不同应用程序利用网络资源而不会相互干扰。端口号最常出现在网络编程中,尤其是套接字编程。但是,有时候,临时用户可以看到端口号。例如,某人在 Internet 上访问的某些网站使用如下 URL:
http://www.mairie-metz.fr:8080/在此示例中,数字 8080 是指 Web 浏览器用于连接到 Web 服务器的端口号。通常,网站使用端口号 80,并且该号码不需要包含在 URL 中(尽管可以)。
在 IP 网络中,端口号理论上可以在 0 到 65535 之间。但是,大多数流行的网络应用程序使用该范围低端的端口号(例如 HTTP 为 80)。
注意:术语端口也指网络技术的其他几个方面。端口可以指外围设备的物理连接点,例如串行端口,并行端口和 USB 端口。术语端口还指某些以太网连接点,例如集线器,交换机或路由器上的连接点。
参考http://compnetworking.about.com/od/basicnetworkingconcepts/l/bldef_port.htm
参考http://compnetworking.about.com/od/itinformationtechnology/l/bldef_socket.htm