ChatGPT解决这个技术问题 Extra ChatGPT

端口和套接字有什么区别?

这是我所在组织的一位软件工程师提出的问题。我对最广泛的定义感兴趣。

重申一下,套接字不仅限于网络 IO。它们可在各种情况下用于在各种应用程序之间传输数据。
您能否举出 2 或 3 个非网络 IO 套接字的示例?
在网络套接字领域,套接字对象是依赖于主机 IP 地址和端口号进行通信的通信隧道。

2
28 revs, 7 users 92%

概括

TCP 套接字是在特定 TCP 连接或侦听状态的上下文中由 IP 地址和端口定义的端点实例。

端口是定义服务端点的虚拟化标识符(不同于服务实例端点,即会话标识符)。

TCP 套接字不是连接,它是特定连接的端点。

可以有到服务端点的并发连接,因为连接由其本地和远程端点标识,从而允许将流量路由到特定的服务实例。

对于给定的地址/端口组合,只能有一个侦听器套接字。

博览会

这是一个有趣的问题,它迫使我重新审视一些我认为我完全了解的事情。您可能会认为“socket”之类的名称是不言自明的:显然选择它是为了唤起您插入网络电缆的端点的图像,具有强大的功能相似性。然而,用网络术语来说,“socket”这个词承载了太多的包袱,以至于需要仔细重新检查。

在最广泛的意义上,端口是入口或出口点。虽然没有在网络环境中使用,但法语单词 porte 的字面意思是门或网关,进一步强调了无论您运送数据还是大型钢制集装箱,港口都是运输端点的事实。

出于讨论的目的,我将把考虑限制在 TCP-IP 网络的上下文中。 OSI 模型非常好,但从未完全实施,更不用说在高流量高压力条件下广泛部署。

IP 地址和端口的组合严格称为端点,有时也称为套接字。这种用法源于 RFC793,即原始 TCP 规范。

TCP 连接由两个端点(即套接字)定义。

端点(套接字)由网络地址和端口标识符的组合定义。请注意,地址/端口并不能完全识别套接字(稍后会详细介绍)。

端口的目的是区分给定网络地址上的多个端点。您可以说端口是虚拟化端点。这种虚拟化使单个网络接口上的多个并发连接成为可能。

它是套接字对(由客户端 IP 地址、客户端端口号、服务器 IP 地址和服务器端口号组成的 4 元组)指定唯一标识 Internet 中每个 TCP 连接的两个端点。 (TCP-IP 图解第 1 卷,W. Richard Stevens)

在大多数 C 派生语言中,TCP 连接是使用 Socket 类实例上的方法建立和操作的。尽管在更高的抽象级别上操作很常见,通常是 NetworkStream 类的实例,但这通常会公开对套接字对象的引用。对于编码人员来说,这个套接字对象似乎代表了连接,因为连接是使用套接字对象的方法创建和操作的。

在 C# 中,要建立 TCP 连接(到现有侦听器),首先需要创建一个 TcpClient。如果您没有为 TcpClient 构造函数指定端点,则它使用默认值 - 一种或另一种定义本地端点的方式。然后在您创建的实例上调用 Connect 方法。此方法需要一个描述另一个端点的参数。

所有这一切都有点令人困惑,并让您相信套接字是一个连接,这是胡说八道。在理查德·多尔曼问这个问题之前,我一直在这种误解下苦苦挣扎。

经过大量阅读和思考,我现在确信拥有一个带有构造函数的类 TcpConnection 会更有意义,该构造函数接受两个参数,LocalEndpoint 和 RemoteEndpoint。当本地端点可以接受默认值时,您可能支持单个参数 RemoteEndpoint。这在多宿主计算机上是不明确的,但可以使用路由表通过选择到远程端点的最短路径的接口来解决不明确性。

清晰度也会在其他方面得到提高。套接字不是通过 IP 地址和端口的组合来识别的:

[...]TCP 使用包含本地和外部地址的所有四个值对传入的段进行解复用:目标 IP 地址、目标端口号、源 IP 地址和源端口号。 TCP 无法仅通过查看目标端口来确定哪个进程获取传入段。此外,在 [给定端口号] 的 [各种] 端点中唯一将接收传入连接请求的端点是处于侦听状态的端点。 (p255,TCP-IP 图解第 1 卷,W. Richard Stevens)

如您所见,网络服务不仅有可能而且很有可能拥有多个具有相同地址/端口的套接字,但在特定地址/端口组合上只有一个侦听器套接字。典型的库实现提供了一个套接字类,它的一个实例用于创建和管理连接。这是非常不幸的,因为它会引起混淆并导致这两个概念的广泛混为一谈。

Hagrawal 不相信我(见评论)所以这是一个真实的样本。我将网络浏览器连接到 http://dilbert.com,然后运行 netstat -an -p tcp。输出的最后六行包含地址和端口不足以唯一标识套接字这一事实的两个示例。 192.168.1.3(我的工作站)和 54.252.94.236:80(远程 HTTP 服务器)之间有两个不同的连接

  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 节的第二段说

连接完全由两端的套接字对指定。本地套接字可能参与到不同外部套接字的许多连接。

从编程的角度来看,套接字的这种定义没有帮助,因为它与套接字对象不同,后者是特定连接的端点。对于程序员来说,这个问题的大多数听众都是程序员,这是一个至关重要的功能差异。

@plugwash 做了一个突出的观察。

根本问题是 TCP RFC 对 socket 的定义与所有主要操作系统和库使用的 socket 定义相冲突。

根据定义,RFC 是正确的。当图书馆滥用术语时,这不会取代 RFC。相反,它给该图书馆的用户施加了理解两种解释并小心措辞和上下文的责任负担。如果 RFC 不同意,则最新且最直接适用的 RFC 优先。

参考

TCP-IP 图解第 1 卷协议,W. Richard Stevens,1994 Addison Wesley RFC793,南加州大学信息科学研究所 DARPA RFC147,套接字的定义,Joel M. Winett,林肯实验室


也许,与关键字 socket 和 port 的真实世界类比会帮助那些赞成这个问题的人。还是很好的解释!
@rationalcoder - 阅读整个答案。被某物定义和被它识别是有区别的。例如,类的实例由类定义。它们部分但不完全被它识别。
它部分由 IP 和端口标识。这足以创建一个。但是只要另一端不同,您可以创建另一个具有相同 IP 和端口的
我没有投票,因为我不同意这个说法——“A socket is not identify by the combination of IP address and port:”..阅读TCP RFC - tools.ietf.org/html/rfc793..很清楚该套接字是IP和端口的组合,如果您知道IP和端口,那么您已经确定了一个套接字或端点,如果您知道一对套接字,即客户端IP +端口和服务器IP +端口,那么您已经确定了一个唯一的连接..
“在上面的示例中,有两个端点的地址/端口组合为 54.252.94.236:80。如果您只有地址和端口,那么您没有足够的信息来区分这些套接字。没有足够的信息来识别一个插座。”不是那些相同的套接字,而是不同的连接,在你有 3 个套接字、2 个本地和一个相同的服务器套接字连接的两个连接之间;还是它们实际上是两个不同的插座?因为它们是相同的,所以无法区分它们,但是要区分连接,您需要不同的本地套接字。
u
user207421

一个套接字由三部分组成:

IP 地址 传输协议 端口号

端口是介于 1 和 65535 之间的数字,表示设备中的逻辑门。客户端和服务器之间的每个连接都需要一个唯一的套接字。

例如:

1030是一个端口。

(10.1.1.2 , TCP , 端口 1030) 是一个套接字。


不,一个套接字由五部分组成:{协议、本地地址、本地端口、远程地址、远程端口}。
@KorayTugay 它在 IP 标头中。是什么让您认为 TCP 层看不到这一点?
@RBT 连接由元组定义,因此构成其端点的套接字也是如此。请参阅 RFC 793。
@EJB 套接字只能通过 IP:Port 识别,而不是 5 元素元组。 RFC 793:为了允许单个主机内的多个进程同时使用 TCP 通信设施,TCP 在每个主机内提供一组地址或端口。与来自互联网通信层的网络和主机地址连接起来,形成一个套接字。
@EJP Still RFC 793:“一对套接字唯一地标识每个连接。也就是说,一个套接字可以同时用于多个连接。”如果一个插座已经由五个东西组成,我的引文中怎么会有“一对插座”?
G
Gucho Ca

套接字代表两个网络应用程序之间的单个连接。这两个应用程序名义上运行在不同的计算机上,但套接字也可以用于单台计算机上的进程间通信。应用程序可以创建多个套接字用于相互通信。套接字是双向的,这意味着连接的任一端都能够发送和接收数据。因此,理论上可以在 OSI 模型从 2 开始的任何级别创建套接字。程序员经常在网络编程中使用套接字,尽管是间接的。像 Winsock 这样的编程库隐藏了套接字编程的许多低级细节。自 1980 年代初以来,套接字已被广泛使用。

端口代表网络通信的端点或“通道”。端口号允许同一台计算机上的不同应用程序使用网络资源而不会相互干扰。端口号最常出现在网络编程中,尤其是套接字编程中。但有时,临时用户可以看到端口号。例如,一个人在 Internet 上访问的某些网站使用如下 URL:

http://www.mairie-metz.fr:8080/ 在此示例中,数字 8080 是指 Web 浏览器用于连接到 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


OSI 模型上的第 2 层是节点之间的连接,它没有连接进程的机制。我不相信您可以考虑 OSI l2 中存在的套接字。
电路是连接 - 套接字是端点。一个连接由 2 个套接字组成。
一个套接字代表两个网络应用程序之间的单个连接。”这与 RFC 793, Transmission Control Protocol 不匹配,它解释了:“允许单个主机内有多个进程为了同时使用 TCP 通信设施,TCP 在每个主机内提供一组地址或端口。与来自 Internet 通信层的网络和主机地址连接起来,形成一个套接字。一对套接字唯一地标识每个连接。"
s
snr

打个比方

虽然上面已经为套接字提供了很多技术性的东西......我想补充一下我的答案,以防万一,如果有人仍然感觉不到 ip、端口和套接字之间的区别

考虑一个服务器 S,

并说人 X、Y、Z 需要来自该服务器 S 的服务(比如聊天服务)

然后

IP 地址告诉 --> 谁?是 X,Y,Z 想要联系的聊天服务器“S”吗

好的,你得到了“谁是服务器”

但是假设服务器'S'也向其他人提供一些其他服务,比如'S'为人A、B、C提供存储服务

然后

端口告诉--->哪个?您(X,Y,Z)需要的服务,即聊天服务而不是存储服务

好吧..,你让服务器知道“聊天服务”是你想要的,而不是存储

你是三岁,服务器可能想以不同的方式识别这三个

插座来了

现在socket告诉-->哪一个?特定连接

也就是说,说,

用于人员 X 的插座 1

Y 人插座 2

和用于人 Z 的插座 3

我希望它可以帮助仍然困惑的人:)


所以 X,Y,Z 会连接到同一个端口,即同一个服务,但在服务器端有不同的套接字?因此,当 X 向服务器发送一些数据包时,它会说:“找到(协议,X 的 IP,X 的端口,S 的 IP,S 的端口)套接字”并发送到聊天应用程序。我假设某些特定于应用程序的对象和套接字对象之间必须存在绑定?例如,当我从 socket-1 获取一些数据时,我想将其显示为用户消息,但应用程序需要知道来自套接字 A 的消息来自 User-X。
佚名

首先,我认为我们应该首先了解从 A 到 B 获取数据包的构成。

网络的一个常见定义是使用 OSI Model,它根据目的将网络分成多个层。有一些重要的,我们将在这里介绍:

数据链路层。该层负责将数据包从一个网络设备传输到另一个网络设备,并且位于实际进行传输的层之上。它谈论 MAC 地址并知道如何根据 MAC(硬件)地址查找主机,但仅此而已。

网络层是允许您跨机器和物理边界(例如物理设备)传输数据的层。网络层必须本质上支持一种额外的基于地址的机制,该机制以某种方式与物理地址相关;输入 Internet 协议 (IPv4)。 IP 地址可以通过 Internet 将您的数据包从 A 传送到 B,但对如何遍历各个跃点一无所知。这是由上层根据路由信息处理的。

传输层。该层负责定义信息从 A 到 B 的获取方式以及对该行为的任何限制、检查或错误。例如,TCP 将附加信息添加到数据包中,以便可以推断数据包是否丢失。

除其他外,TCP 包含 ports 的概念。这些实际上是 Internet 套接字 (AF_INET) 可以绑定到的同一 IP 地址上的不同数据端点。

碰巧,so too does UDP 和其他传输层协议。从技术上讲,它们需要具有端口,但这些端口确实为上层中的多个应用程序提供了一种使用同一台计算机接收(并确实建立)传出连接的方法。

这将我们带到 TCP 或 UDP 连接的剖析。每个都有一个源端口和地址,以及一个目标端口和地址。这样一来,在任何给定的会话中,目标应用程序都可以从源端进行响应和接收。

因此,端口本质上是一种规范授权的方式,允许多个并发连接共享同一地址。

现在,我们需要看看您如何从应用程序的角度与外界进行通信。为此,您需要询问您的操作系统,并且由于大多数操作系统都支持 Berkeley Sockets 的处理方式,我们可以看到我们可以创建涉及来自应用程序的端口的套接字,如下所示:

int fd = socket(AF_INET, SOCK_STREAM, 0); // tcp socket
int fd = socket(AF_INET, SOCK_DGRAM, 0); // udp socket
// later we bind...

伟大的!因此,在 sockaddr 结构中,我们将指定我们的端口和 bam!任务完成!好吧,几乎,除了:

int fd = socket(AF_UNIX, SOCK_STREAM, 0);

也是可能的。呃,这是在工作中扔了一个扳手!

好吧,实际上它没有。我们需要做的就是提出一些适当的定义:

互联网套接字是 IP 地址、协议及其相关端口号的组合,服务可以在该端口号上提供数据。所以 tcp 端口 80,stackoverflow.com 是一个互联网套接字。

unix 套接字是文件系统中表示的 IPC 端点,例如 /var/run/database.sock。

套接字 API 是一种请求应用程序能够读取和写入数据到套接字的方法。

瞧!那收拾东西了。所以在我们的计划中,

端口是一个数字标识符,作为传输层协议的一部分,它标识应该响应给定请求的服务号。

所以实际上,端口是形成互联网套接字的要求的一个子集。不幸的是,碰巧socket这个词的含义已经被应用于几种不同的想法。所以我衷心建议你命名你的下一个项目套接字,只是为了增加混乱;)


这就是子弹不会离开也不会离开 Powerpoint 的原因;他们工作!
非常好的介绍 tcp-ip 和网络通信。初学者,请先阅读本文。
G
Gishu

一个套接字 = IP 地址 + 一个端口(数字地址) 它们一起标识了机器上网络连接的端点。 (我只是不及格网络 101 吗?)


我相信端口的含义比您的定义更广泛。
并且套接字不仅受制于 TCP/IP 堆栈。一般参见 UNIX 域套接字或进程间通信套接字。
不确定这个答案。您可以使用 HTTP 通过套接字与另一个进程进行通信,而无需分配端口。
c
cheznead

通常,您会获得很多理论知识,但区分这两个概念的最简单方法之一如下:

为了获得服务,您需要一个服务号码。此服务号称为端口。就那么简单。

例如,作为服务的 HTTP 在端口 80 上运行。

现在,许多人可以请求该服务,并且建立了来自客户端-服务器的连接。会有很多联系。每个连接代表一个客户端。为了维护每个连接,服务器为每个连接创建一个套接字以维护其客户端。


每个套接字都需要自己的端口吗?
我不确定您的陈述是否正确:“服务器为每个连接创建套接字以维护其客户端”是否正确。
@RushiAgrawal 那我建议你查一下。具体看 man accept。
这意味着对于服务器为每个连接创建以维护其客户端的每个套接字,可以具有相同的端口号(例如用于 HTTP 连接继续的端口 80),但具有发送连接请求的客户端的不同 IP 地址。正确的?
服务器为每个连接创建一个套接字实例。这里的问题是英语与类和实例模棱两可。
M
Mosab Shaheen

这些是基本的网络概念,因此我将以简单而全面的方式对其进行解释,以便详细了解。

套接字就像电话(即用于通信的端到端设备)

IP 就像您的电话号码(即您的套接字的地址)

端口就像您想与之交谈的人(即您想从该地址订购的服务)

套接字可以是客户端或服务器套接字(即在公司中,客户支持的电话是服务器,但您家中的电话主要是客户端)

因此网络中的套接字是绑定到一对(ip,端口)=(地址,服务)的虚拟通信设备。

笔记:

一台机器、一台计算机、一台主机、一部手机或一台 PC 可以有多个地址、多个开放端口,因此也可以有多个套接字。就像在办公室里一样,您可以拥有多个电话号码和多个可以交谈的电话。

开放/活动端口的存在需要您必须绑定一个套接字,因为它是使端口可访问的套接字。但是,您可能暂时有未使用的端口。

另请注意,在服务器套接字中,您可以将其绑定到(端口,机器的特定地址)或(端口,机器的所有地址),因为在电话中您可以连接许多电话线(电话号码)到一部电话或一条特定的电话线到电话,您仍然可以通过所有这些电话线或通过特定的电话线联系到一个人。

您不能像电话中那样将一个套接字与两个端口关联(绑定)通常您不能总是让两个人同时使用同一部电话。

高级:在同一台机器上,您不能有两个具有相同类型(客户端或服务器)以及相同端口和 ip 的套接字。但是,如果您是客户端,则可以使用两个套接字打开到服务器的两个连接,因为每个客户端套接字中的本地端口都不同)

希望能解开你的疑惑


在这个问题下看到所有这些对套接字/端口/IP地址的理解和类比是很有趣的。我喜欢这个答案。
哇!多么好的解释和例子。为此+1。
M
Mark Brackett

似乎有很多答案将套接字等同于两台 PC 之间的连接。我认为这是绝对不正确的。套接字一直是 1 台 PC 上的端点,它可能已连接也可能未连接 - 当然,我们都曾在某些时候使用过侦听器或 UDP 套接字*。重要的部分是它是可寻址的和活跃的。向 1.1.1.1:1234 发送消息不太可能工作,因为没有为该端点定义套接字。

套接字是特定于协议的 - 因此 TCP/IPUDP/IP 使用* (ipaddress:port) 的唯一性实现不同于 IPX(网络、节点和...咳咳,套接字 - 但与一般“套接字”术语所指的套接字不同。IPX 套接字编号等同于 IP 端口)。但是,它们都提供了一个独特的可寻址端点。

由于 IP 已成为主导协议,端口(在网络术语中)已成为 UDP 或 TCP 端口号的同义词——它是套接字地址的一部分。

UDP 是无连接的——这意味着两个端点之间没有创建任何虚拟电路。但是,我们仍然将 UDP 套接字称为端点。 API 函数清楚地表明两者只是不同类型的套接字 - SOCK_DGRAM 是 UDP(只是发送消息),SOCK_STREAM 是 TCP(创建虚拟电路)。

从技术上讲,IP 标头保存 IP 地址,IP 之上的协议(UDP 或 TCP)保存端口号。这使得有其他协议成为可能(例如,没有端口号但有 IP 地址信息的 ICMP)。


插座的好答案。端口确实是指TCP或UDP,我想强调的是,不一定是在IP之上使用。
d
dkinzer

简短的回答。

端口可以描述为主机内标识程序或进程的内部地址。

套接字可以被描述为一种编程接口,允许程序与互联网上或本地的其他程序或进程进行通信。


端口描述中的“内部”一词对我来说听起来很像“非公开”。
那么我们可以说:Sockets 在 Ports 内部运行吗?或 Ports 在 Sockets 内运行?
@GuchoCa我们不能说套接字或端口都在运行,更不用说一个在另一个内部了。不清楚你在问什么。
R
Roel

它们是来自两个不同领域的术语:“端口”是 TCP/IP 网络的概念,“套接字”是 API(编程)事物。通过获取端口和主机名或网络适配器并将它们组合成可用于发送或接收数据的数据结构来制作“套接字”(在代码中)。


对于最一般的答案,请点击“通过获取端口和主机名或网络适配器并将它们组合成一个。”例如,UNIX 套接字(在代码中)是一种数据结构(或对象),您可以使用它来发送或接收数据。
C
Colin

在阅读了优秀的投票答案后,我发现以下几点需要强调一下,我是网络编程的新手:

TCP-IP 连接是将一个地址:端口组合与另一个地址:端口组合连接起来的双向路径。因此,每当您打开从本地计算机到远程服务器上的端口(例如 www.google.com:80)的连接时,您也将计算机上的新端口号与连接相关联,以允许服务器发送事情还给你,(例如 127.0.0.1:65234)。使用 netstat 查看机器的连接会很有帮助:

> netstat -nWp tcp (on OS X)
Active Internet connections
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)    
tcp4       0      0  192.168.0.6.49871      17.172.232.57.5223     ESTABLISHED
...

M
Mecki

套接字是一个通信端点。套接字与 TCP/IP 协议族没有直接关系,它可以与系统支持的任何协议一起使用。 C 套接字 API 要求您首先从系统中获取一个空白套接字对象,然后您可以将其绑定到本地套接字地址(直接检索无连接协议的传入流量或接受面向连接协议的传入连接请求)或者您可以连接到远程套接字地址(对于任何一种协议)。如果你想同时控制这两者,你甚至可以同时控制一个套接字绑定到的本地套接字地址和一个套接字连接到的远程套接字地址。对于无连接协议,连接套接字甚至是可选的,但如果你不这样做,你还必须将目标地址与你想通过套接字发送的每个数据包一起传递,因为套接字如何知道发送到哪里这个数据到?优点是您可以使用单个套接字将数据包发送到不同的套接字地址。一旦你配置了你的套接字,甚至可以连接,就把它看作是一个双向通信管道。您可以使用它将数据传递到某个目的地,而某些目的地可以使用它将数据传回给您。您写入套接字的内容被发送出去,收到的内容可供阅读。

另一方面,端口是只有 TCP/IP 协议栈的某些协议才有的东西。 TCP 和 UDP 数据包都有端口。端口只是一个简单的数字。源端口和目标端口的组合标识了两个主机之间的通信通道。例如,您可能有一个服务器,它应该是一个简单的 HTTP 服务器和一个简单的 FTP 服务器。如果现在有一个数据包到达该服务器的地址,它如何知道该数据包是发往 HTTP 还是 FTP 服务器?好吧,它会知道,因为 HTTP 服务器将在端口 80 上运行,而 FTP 服务器在端口 21 上运行,所以如果数据包以目标端口 80 到达,则它是用于 HTTP 服务器而不是 FTP 服务器。数据包还有一个源端口,因为没有这样的源端口,服务器一次只能有一个连接到一个 IP 地址。源端口使服务器可以区分其他相同的连接:它们都具有相同的目标端口,例如端口 80、相同的目标 IP(服务器的 IP)和相同的源 IP,因为它们都来自相同的客户端,但由于它们的源端口不同,服务器可以将它们相互区分。当服务器发回回复时,它会对请求来自的端口执行此操作,这样客户端也可以区分它从同一服务器收到的不同回复。


这是不正确的。套接字不是端点。一个套接字由两个端点定义。每个端点都由一个网络地址和一个端口定义。端口的目的是区分同一网络地址上的多个端点,从而可以支持多个并发套接字。
我注意到 RFC793(原始 TCP 规范)确实将网络地址和端口的组合称为套接字,所以我可以看到你从哪里得到这个,但它仍然不正确,因为套接字必须由两个端点定义。
经过反思,文献是矛盾的,我道歉。非常严格地说,只有在两个端点(又名套接字)之间建立 TCP 连接后,才会发生通信,每个端点都由网络地址和端口标识。我放弃。
@PeterWone我相信您不能通过两个端点定义套接字:等待传入连接的服务器套接字呢?它是单独的,但它仍然是一个套接字。而且您甚至无法定义与网络相关的套接字..您可能在文件上有套接字。是的,网络地址+端口是一个套接字,但我打算将一个套接字作为超集。
@Jack 是的,在此评论中,我错误地使用了术语套接字,您也是如此,正如您自己的侦听套接字示例所展示的那样。我自己在上面的回答详细讨论并参考了正确的命名法及其确切含义。我们在这个问题的评论中所说的套接字是由两个端点定义的连接,每个端点都是一个套接字。
K
Krishna

套接字是一种特殊类型的文件句柄,进程使用它向操作系统请求网络服务。套接字地址是三元组:{protocol, local-address, local-process},其中本地进程由端口号标识。

在 TCP/IP 套件中,例如:

{tcp, 193.44.234.3, 12345}

对话是两个进程之间的通信链接,因此描绘了两个进程之间的关联。关联是完全指定组成连接的两个进程的 5 元组:{protocol, local-address, local-process, foreign-address, foreign-process}

在 TCP/IP 套件中,例如:

{tcp, 193.44.234.3, 1500, 193.44.234.5, 21}

可能是一个有效的关联。

半关联是:{protocol, local-address, local-process}

或者

{协议,外国地址,外国进程}

指定连接的每一半。

半关联也称为套接字或传输地址。也就是说,套接字是可以在网络中命名和寻址的通信端点。套接字接口是通信协议的几个应用程序编程接口 (API) 之一。设计为通用通信编程接口,它首先由 4.2BSD UNIX 系统引入。虽然还没有标准化,但已经成为事实上的行业标准。


这个答案是为我做的。我想这是因为没有人提到联想这个词。很好的解释。
您的任何示例中都没有进程号。您正在寻找的词是“端口”。
阅读第一段。那里清楚地提到了。通过引用确切的短语让我知道任何歧义。这对我即兴创作很有帮助。
我读了。正确的表述是“套接字地址是三元组:{protocol, local-address, local-port-number]”。一个进程可以拥有多个端口,这使您的公式无效。
C
Community

套接字地址是 IP 地址和端口号

123.132.213.231         # IP address
               :1234    # port number
123.132.213.231:1234    # socket address

当 2 个套接字绑定在一起时,就会发生连接。


没有将两个套接字绑定在一起这样的事情。 “绑定”这个词意味着与端口有关的其他东西。
这是错误的,套接字不需要 IP 地址或端口号,只有一些网络套接字需要它们。 Unix 域套接字和 socketCAN 套接字都不需要它们。
U
Ugnes

https://i.stack.imgur.com/4APkp.png


i
inf3rno

端口是最简单的部分,它只是套接字的唯一标识符。套接字是进程可以用来建立连接和相互通信的东西。 Tall Jeff 有一个很好的电话类比,但并不完美,所以我决定修复它:

ip和端口~电话号码

插座〜电话设备

连接~电话

建立连接~呼叫号码

进程,远程应用程序〜人

消息~演讲


很好的说明(尤其是当您考虑电话交换历史是网络术语基础的一部分时..)
看看 netstat 显示一段时间。从侦听套接字接受的所有套接字共享同一个端口。 所以端口不是套接字的唯一标识符。
S
S.Lott

套接字是软件中的一种结构。它或多或少是一个文件。它具有读写等操作。这不是物理上的事情。这是您的软件引用物理事物的一种方式。

端口是类似设备的东西。每台主机都有一个或多个网络(这些是物理的);主机在每个网络上都有一个地址。每个地址可以有数千个端口。

只有一个套接字可能正在使用某个地址的端口。套接字分配端口类似于为文件系统 I/O 分配设备。一旦分配了端口,就没有其他套接字可以连接到该端口。当套接字关闭时,端口将被释放。

看看TCP/IP Terminology


对套接字的这种描述非常离谱。套接字是关于一对元组之间的连接,其中元组指的是 IP ADDR 和端口对。此外,许多套接字可以连接到同一个端口。您认为 Web 服务器如何在端口 80 上进行多个连接?这是一个糟糕的答案
对不起。多个套接字未连接到端口 80。一个套接字已连接并在实际传输发生的地方生成其他套接字。请参阅opengroup.org/onlinepubs/009695399/functions/listen.html
实际上,opengroup.org/onlinepubs/009695399/functions/connect.html 处的描述更好。连接返回的对等套接字不在端口 80 上。
这篇文章在一些细节上是不正确的,并且在几个方面具有误导性。
@Peter Wone:哪些细节?哪些方面?希望从我的错误中吸取教训。
u
user207421

来自 Oracle Java Tutorial

套接字是网络上运行的两个程序之间双向通信链路的一个端点。套接字绑定到端口号,以便 TCP 层可以识别数据要发送到的应用程序。


这只是一个教程,当然不是规范性参考。
“套接字是双向通信链路的一个端点”这不是套接字定义,不是Java教程吗?
@prayagupd 当然这是一个定义,但它来自教程,而不是规范。
P
Pang

端口和套接字可以比作银行分行。

“银行”的楼号类似于IP地址。银行有不同的部分,例如:

储蓄账户部 个人贷款部 房贷部 申诉部

所以1(储蓄账户部门)、2(个人贷款部门)、3(房贷部门)和4(申诉部门)是端口。

现在让我们说你去开一个储蓄账户,你去银行(IP地址),然后你去“储蓄账户部门”(端口号1),然后你会遇到一个在“储蓄账户部门”工作的员工”。让我们称他为 SAVINACCOUNT_EMPLOYEE1 来开户。

SAVINGACCOUNT_EMPLOYEE1 是您的套接字描述符,因此可能有 SAVINGACCOUNT_EMPLOYEE1 到 SAVINGACCOUNT_EMPLOYEEN。这些都是套接字描述符。

同样,其他部门将有员工在他们手下工作,它们类似于套接字。


b
balaweblog

港口:

端口可以指外围设备的物理连接点,例如串行、并行和 USB 端口。端口一词也指某些以太网连接点,例如集线器、交换机或路由器上的连接点。

插座:

套接字代表两个网络应用程序之间的单个连接。这两个应用程序名义上运行在不同的计算机上,但套接字也可以用于单台计算机上的进程间通信。应用程序可以创建多个套接字用于相互通信。套接字是双向的,这意味着连接的任一端都能够发送和接收数据。


TCP 或 UDP 端口不指代任何物理或以太网连接点。你还没有回答问题。
@ user207421我在问题中没有关于TCP或UDP的任何内容。
你不需要的是任何关于“物理连接点”的东西。这是不正确的。端口是一个逻辑实体,根本不涉及任何物理实体。
T
Tall Jeff

我认为这个问题暗示了相对 TCP/IP 术语。通俗地说:

PORT 就像特定邮政编码中特定房屋的电话号码。镇的邮政编码可以被认为是该镇和该镇所有房屋的 IP 地址。

另一方面,SOCKET 更像是在一对房子的电话之间建立的电话通话。可以在同一城镇的房屋之间或不同城镇的两所房屋之间建立这些呼叫。 SOCKET 就是这对电话之间相互通话的临时建立的通路。


套接字是一个端点。它存在于建立连接之前(TCP),或者在没有连接的情况下(UDP)。因此,它本身并不是连接。
S
Sander

套接字是一种数据 I/O 机制。端口是通信协议的合同概念。套接字可以在没有端口的情况下存在。一个端口可以在没有特定套接字的情况下存在(例如,如果多个套接字在同一个端口上处于活动状态,这对于某些协议可能是允许的)。

端口用于确定接收方应将数据包路由到哪个套接字,有许多协议,但并不总是需要,并且可以通过其他方式完成接收套接字的选择 - 端口完全是协议处理程序使用的工具网络子系统。例如,如果协议不使用端口,则数据包可以到达所有侦听套接字或任何套接字。


H
Harty

从广义上讲,Socket - 就是一个插座,就像你的电气、电缆或电话插座一样。 “必要的东西”(电源、信号、信息)可以进出的点。它隐藏了很多详细的东西,这对于使用“必要的东西”来说是不需要的。用软件术语来说,它提供了一种定义两个实体之间通信机制的通用方法(这些实体可以是任何东西——两个应用程序、两个物理上独立的设备、操作系统中的用户和内核空间等)

端口是端点鉴别器。它将一个端点与另一个端点区分开来。在网络级别,它将一个应用程序与另一个应用程序区分开来,以便网络堆栈可以将信息传递给适当的应用程序。


r
rofrol

Socket 是内核为用户应用程序提供的用于数据 I/O 的抽象。套接字类型由它所处理的协议、IPC 通信等定义。因此,如果有人创建了 TCP 套接字,他可以通过简单的方法和较低级别的协议处理(如 TCP 转换和将数据包转发到较低级别的网络协议是由内核中的特定套接字实现完成的。优点是用户不必担心处理协议特定的细节,而应该像普通缓冲区一样读取和写入数据到套接字。在 IPC 的情况下也是如此,用户只是读取和写入数据到套接字,内核根据创建的套接字类型处理所有较低级别的细节。

端口与 IP 一起就像为套接字提供一个地址,虽然它不是必需的,但它有助于网络通信。


V
VoidPointer

端口表示 IP 网络协议的 TCP 和 UDP 传输中的通信端点。套接字是这些协议(套接字 API)实现中常用的通信端点的软件抽象。另一种实现是 XTI/TLI API。

也可以看看:

Stevens,WR 1998,UNIX 网络编程:网络 API:套接字和 XTI;第 1 卷,普伦蒂斯·霍尔。 Stevens,WR,1994,TCP/IP 图解,第 1 卷:协议,Addison-Wesley。


u
user207421

套接字基本上是网络通信的端点,至少由一个 IP 地址和一个端口组成。在 Java/C# 中,套接字是双向连接一侧的更高级别实现。

此外,Java Tutorial 中的(非规范性)定义。


O
Omkar Ramtekkar

已经对这个问题给出了理论上的答案。我想对这个问题举一个实际的例子,这将清楚你对 Socket 和 Port 的理解。

我找到了here

此示例将引导您完成连接到网站(例如 Wiley)的过程。您将打开您的网络浏览器(如 Mozilla Firefox)并在地址栏中输入 www.wiley.com。您的 Web 浏览器使用域名系统 (DNS) 服务器来查找名称 www.wiley.com 以识别其 IP 地址。对于此示例,地址为 192.0.2.100。 Firefox 连接到 192.0.2.100 地址和应用层 Web 服务器运行的端口。 Firefox 知道预期的端口,因为它是众所周知的端口。 Web 服务器的著名端口是 TCP 端口 80。Firefox 尝试连接的目标套接字写为 socket:port,或在本例中为 192.0.2.100:80。这是连接的服务器端,但服务器需要知道将您想在 Mozilla Firefox 中查看的网页发送到哪里,因此您也有一个用于连接客户端的套接字。客户端连接由您的 IP 地址(例如 192.168.1.25)和随机选择的动态端口号组成。与 Firefox 关联的套接字看起来像 192.168.1.25:49175。因为 Web 服务器在 TCP 端口 80 上运行,所以这两个套接字都是 TCP 套接字,而如果您连接到在 UDP 端口上运行的服务器,则服务器和客户端套接字都是 UDP 套接字。


引用质量很差。第三段误用了“socket”这个词,好像它的意思是“IP地址”。它没有。
g
guest

单个端口可以有一个或多个与不同外部 IP 连接的插座,例如多个电源插座。

  TCP    192.168.100.2:9001     155.94.246.179:39255   ESTABLISHED     1312
  TCP    192.168.100.2:9001     171.25.193.9:61832     ESTABLISHED     1312
  TCP    192.168.100.2:9001     178.62.199.226:37912   ESTABLISHED     1312
  TCP    192.168.100.2:9001     188.193.64.150:40900   ESTABLISHED     1312
  TCP    192.168.100.2:9001     198.23.194.149:43970   ESTABLISHED     1312
  TCP    192.168.100.2:9001     198.49.73.11:38842     ESTABLISHED     1312

D
Dražen G.

Socket 是网络端点的 SW 抽象,用作应用程序的接口。在 Java 中,C# 由对象表示,在 Linux 中,Unix 是文件。

如果要建立通信,端口只是您指定的套接字的属性。要从套接字接收数据包,您必须将其绑定到特定的本地端口和 NIC(具有本地 IP 地址)或所有 NIC(在绑定调用中指定 INADDR_ANY)。要发送数据包,您必须指定远程套接字的端口和 IP。