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


当前回答

相对的TCP/IP术语,我认为这是隐含的问题。通俗地说:

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

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

其他回答

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

参见:

史蒂文斯,W. R. 1998, UNIX网络编程:网络api:套接字和XTI;第一卷,普伦蒂斯大厅。 Stevens, W. R., 1994, TCP/IP图解,第1卷:协议,Addison-Wesley。

总结

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

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

TCP套接字不是一个连接,而是一个特定连接的端点。

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

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

博览会

这是一个有趣的问题,它迫使我重新审视一些我自以为已经完全了解的东西。你可能会认为“插座”这样的名字是不言自明的:选择它显然是为了唤起你插入网线的端点的形象,有很强的功能相似之处。然而,在网络用语中,“套接字”这个词承载了如此多的负担,以至于有必要仔细地重新检查。

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

为了本讨论的目的,我将只考虑TCP-IP网络的上下文。OSI模型非常好,但从未完全实现,更不用说在高流量、高压力条件下广泛部署。

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

TCP连接由两个端点定义,也就是套接字。

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

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

它是套接字对(4元组) 包括客户端IP地址, 客户端端口号,服务器IP地址, 和服务器端口号)指定 这两个端点唯一 对象中的每个TCP连接 互联网。(TCP-IP插图卷1,W. Richard Stevens)

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

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

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

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

在其他方面,透明度也将得到提高。套接字不能通过IP地址和端口的组合来识别:

[...]TCP demultiplexes incoming segments using all four values that comprise the local and foreign addresses: destination IP address, destination port number, source IP address, and source port number. TCP cannot determine which process gets an incoming segment by looking at the destination port only. Also, the only one of the [various] endpoints at [a given port number] that will receive incoming connection requests is the one in the listen state. (p255, TCP-IP Illustrated Volume 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。

我认为哈格拉瓦尔的误解源于我对“认同”一词的谨慎使用。我的意思是“完全的,明确的,唯一的识别”。在上面的示例中,有两个端点的地址/端口组合为54.252.94.236:80。如果你只有地址和端口,你没有足够的信息来区分这些套接字。这些信息不足以识别套接字。

齿顶高

RFC793第2.7节第2段说

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

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

@plugwash提出了一个显著的观察。

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

根据定义,RFC是正确的。当一个标准库误用术语时,它不会取代RFC。相反,它给该库的用户带来了一种责任负担,即理解两种解释,并小心用词和上下文。如果RFC不一致,则最新的和最直接适用的RFC优先。

参考文献

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

套接字允许在单个应用程序中两个应用程序之间进行通信 机器还是两台机器。实际上它就像门。如果门开了,就可以 是门内进程或应用程序之间的连接 在门外。

套接字有4种类型:

流套接字 数据报套接字 原始套接字 顺序数据包套接字。

套接字主要用于客户机-服务器应用程序。端口标识网络地址上的不同端点。它包含一个数值。总的来说,套接字是端口和网络地址的组合。

这个问题已经有了理论上的答案。我想举一个实际的例子来解释这个问题,让大家对Socket和Port有一个更清晰的理解。

我在这里找到的

This example will walk you thru the process of connecting to a website, such as Wiley. You would open your web browser (like Mozilla Firefox) and type www.wiley.com into the address bar. Your web browser uses a Domain Name System (DNS) server to look up the name www.wiley.com to identify its IP address is. For this example, the address is 192.0.2.100. Firefox makes a connection to the 192.0.2.100 address and to the port where the application layer web server is operating. Firefox knows what port to expect because it is a well-known port . The well-known port for a web server is TCP port 80. The destination socket that Firefox attempts to connect is written as socket:port, or in this example, 192.0.2.100:80. This is the server side of the connect, but the server needs to know where to send the web page you want to view in Mozilla Firefox, so you have a socket for the client side of the connection also. The client side connection is made up of your IP address, such as 192.168.1.25, and a randomly chosen dynamic port number. The socket associated with Firefox looks like 192.168.1.25:49175. Because web servers operate on TCP port 80, both of these sockets are TCP sockets, whereas if you were connecting to a server operating on a UDP port, both the server and client sockets would be UDP sockets.

Socket is an abstraction provided by kernel to user applications for data I/O. A socket type is defined by the protocol it's handling, an IPC communication etc. So if somebody creates a TCP socket he can do manipulations like reading data to socket and writing data to it by simple methods and the lower level protocol handling like TCP conversions and forwarding packets to lower level network protocols is done by the particular socket implementation in the kernel. The advantage is that user need not worry about handling protocol specific nitigrities and should just read and write data to socket like a normal buffer. Same is true in case of IPC, user just reads and writes data to socket and kernel handles all lower level details based on the type of socket created.

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