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


当前回答

An application consists of pair of processes which communicate over the network (client-server pair). These processes send and receive messages, into and from the network through a software interface called socket. Considering the analogy presented in the book "Computer Networking: Top Down Approach". There is a house that wants to communicate with other house. Here, house is analogous to a process, and door to a socket. Sending process assumes that there is a infrastructure on the other side of the door that will transport the data to the destination. Once the message is arrived on the other side, it passes through receiver's door (socket) into the house (process). This illustration from the same book can help you: Sockets are part of transport layer, which provides logical communication to applications. This means that from application's point of view both hosts are directly connected to each other, even though there are numerous routers and/or switches between them. Thus a socket is not a connection itself, it's the end point of the connection. Transport layer protocols are implemented only on hosts, and not on intermediate routers. Ports provide means of internal addressing to a machine. The primary purpose it to allow multiple processes to send and receive data over the network without interfering with other processes (their data). All sockets are provided with a port number. When a segment arrives to a host, the transport layer examines the destination port number of the segment. It then forwards the segment to the corresponding socket. This job of delivering the data in a transport layer segment to the correct socket is called de-multiplexing. The segment's data is then forwarded to the process attached to the socket.

其他回答

总结

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,林肯实验室

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

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

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

单个端口可以有一个或多个连接不同外部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

A socket represents a single connection between two network applications. These two applications nominally run on different computers, but sockets can also be used for interprocess communication on a single computer. Applications can create multiple sockets for communicating with each other. Sockets are bidirectional, meaning that either side of the connection is capable of both sending and receiving data. Therefore a socket can be created theoretically at any level of the OSI model from 2 upwards. Programmers often use sockets in network programming, albeit indirectly. Programming libraries like Winsock hide many of the low-level details of socket programming. Sockets have been in widespread use since the early 1980s.

端口表示网络通信的端点或“通道”。端口号允许同一计算机上的不同应用程序在不相互干扰的情况下利用网络资源。端口号最常出现在网络编程中,尤其是套接字编程中。但是,有时端口号对普通用户是可见的。例如,一个人在因特网上访问的一些网站使用如下URL:

http://www.mairie-metz.fr:8080/在本例中,数字8080指Web浏览器连接到Web服务器所使用的端口号。通常,Web站点使用端口号80,该端口号不需要包含在URL中(尽管可以包含)。

在IP组网中,端口号理论上可以在0到65535之间。但是,大多数流行的网络应用程序使用范围较低的端口号(例如HTTP的80)。

注意:术语端口还指网络技术的其他几个方面。端口可以指外部设备的物理连接点,如串口、并口和USB端口。术语端口也指某些以太网连接点,例如集线器、交换机或路由器上的连接点。

ref http://compnetworking.about.com/od/basicnetworkingconcepts/l/bldef_port.htm

ref http://compnetworking.about.com/od/itinformationtechnology/l/bldef_socket.htm

端口:

端口可以指物理连接点 用于外部设备,如串行、并行和USB端口。 术语端口也指某些以太网连接点 如集线器、交换机或路由器上的那些。

套接字:

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