端口和套接字有什么区别?
这是我组织中的一位软件工程师提出的问题。我对最广泛的定义感兴趣。
解决方案
套接字= IP地址+端口(数字地址)
它们一起确定了机器上网络连接的端点。 (我刚刚使网络101失效了吗?)
套接字表示两个网络应用程序之间的单个连接。这两个应用程序名义上可以在不同的计算机上运行,但是套接字也可以用于单台计算机上的进程间通信。应用程序可以创建多个用于相互通信的套接字。套接字是双向的,这意味着连接的任一端都能够发送和接收数据。
因此,理论上可以在OSI模型的任何级别(从2开始)上创建套接字。程序员经常在网络编程中使用套接字,尽管是间接的。诸如Winsock之类的编程库隐藏了套接字编程的许多底层细节。自1980年代初以来,插座已被广泛使用。
端口代表网络通信的端点或者"通道"。端口号允许同一台计算机上的不同应用程序利用网络资源而不会互相干扰。端口号最常出现在网络编程中,尤其是套接字编程中。但是,有时候,临时用户可以看到端口号。例如,某人在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
它们是来自两个不同领域的术语:"端口"是TCP / IP网络的概念,"套接字"是API(编程)。通过使用端口和主机名或者网络适配器并将它们组合成可用于发送或者接收数据的数据结构来制作(以代码形式)的"套接字"。
套接字基本上是网络通信的端点,至少由一个IP地址和一个端口组成。在Java / Ca套接字中,是双向连接一侧的更高级别的实现。
另外,Java文档中的定义。
套接字是一种数据I / O机制。端口是通信协议的合同概念。套接字可以不带端口而存在。端口可以不存在特定的套接字而存在(例如,如果同一端口上有多个套接字处于活动状态,则某些协议可能允许使用)。
端口用于通过多种协议来确定接收方应将数据包路由到哪个套接字,但这并不总是必需的,并且可以通过其他方式来选择接收套接字,端口完全是协议处理程序使用的工具。网络子系统。例如如果协议不使用端口,则数据包可以转到所有侦听套接字或者任何套接字。
套接字是软件中的结构。它或者多或者少是一个文件;它具有读取和写入之类的操作。这不是物理上的事情;这是软件引用物理事物的一种方式。
端口是类似设备的东西。每个主机都有一个或者多个网络(物理网络);主机在每个网络上都有一个地址。每个地址可以具有数千个端口。
一个插座只能使用某个地址的端口。套接字大致为端口分配端口,就像为文件系统I / O分配设备一样。分配端口后,没有其他套接字可以连接到该端口。关闭插座后,该端口将被释放。
看一下TCP / IP术语。
港口:
端口可以引用物理连接点
适用于串行,并行和USB端口等外围设备。
"端口"一词也指某些以太网连接点,例如
例如集线器,交换机或者路由器上的那些。
插座:
套接字表示两个网络应用程序之间的单个连接。
这两个应用程序名义上可以在不同的计算机上运行,
但是套接字也可以用于单台计算机上的进程间通信。
应用程序可以创建多个用于相互通信的套接字。
套接字是双向的,这意味着连接的任一端都能够发送和接收数据。
套接字是通信端点。套接字与TCP / IP协议系列没有直接关系,它可以与系统支持的任何协议一起使用。 C套接字API希望我们首先从系统中获取一个空白套接字对象,然后可以将其绑定到本地套接字地址(直接检索无连接协议的传入流量,或者接受面向连接协议的传入连接请求)或者我们可以连接到远程套接字地址(对于任何一种协议)。如果要控制两者,绑定到套接字的本地套接字地址和连接到套接字的远程套接字地址,甚至可以同时执行这两个操作。对于无连接协议,连接套接字甚至是可选的,但是如果我们不这样做,则还必须将要通过套接字发送的每个数据包都传递给目标地址,否则套接字将如何知道将其发送到哪里这个数据到?优点是我们可以使用单个套接字将数据包发送到不同的套接字地址。一旦我们配置了套接字,甚至可能将其连接,就可以将其视为双向通信管道。我们可以使用它将数据传递到某个目标,而某些目标可以使用它将数据传递回我们。我们写入套接字的内容将被发送出去,而接收到的内容可用于读取。
另一方面,端口是只有TCP / IP协议栈的某些协议才具有的端口。 TCP和UDP数据包具有端口。端口只是一个简单的数字。源端口和目标端口的组合标识了两个主机之间的通信通道。例如。我们可能拥有同时为简单的HTTP服务器和简单的FTP服务器的服务器。如果现在有一个到达该服务器地址的数据包,那么它将如何知道这是HTTP还是FTP服务器的数据包?好吧,它将知道HTTP服务器将在端口80上运行,而FTP服务器将在端口21上运行,因此,如果数据包通过目标端口80到达,则该数据包将用于HTTP服务器而不是FTP服务器。数据包还具有一个源端口,因为如果没有这样的源端口,则服务器一次只能与一个IP地址建立一个连接。源端口使服务器可以区分其他方面相同的连接:它们都具有相同的目标端口,例如端口80,相同的目标IP,始终相同的服务器地址和相同的源IP,因为它们都来自同一客户端,但是由于它们具有不同的源端口,因此服务器可以将它们彼此区分开。当服务器发回答复时,它将发送到请求所来自的端口,这样客户端也可以区分收到的不同答复。
端口表示IP网络协议在TCP和UDP传输中的通信端点。套接字是通常在这些协议(套接字API)的实现中使用的通信端点的软件抽象。一种替代实现是XTI / TLI API。
也可以看看:
史蒂文斯(Stevens),W。R.,1998年,《 UNIX网络编程:网络API:套接字和XTI》;第1卷,Prentice Hall。
Stevens,W. R.,1994年,《 TCP / IP图解》,第1卷:协议,Addison-Wesley。
问题所隐含的是我假设的相对TCP / IP术语。用外行的话来说:
PORT就像是特定邮政编码中特定房屋的电话号码。城镇的邮政编码可以被认为是城镇以及该城镇中所有房屋的IP地址。
另一方面,SOCKET更像是一对彼此通话的房屋的电话之间建立的电话。可以在同一城镇的房屋之间或者不同城镇的两座房屋之间建立这些呼叫。 SOCKET就是这对相互通话的电话之间的临时建立的路径。
概括
TCP套接字是在特定TCP连接或者侦听状态的上下文中由IP地址和端口定义的终结点实例。
端口是定义服务端点的虚拟化标识符(与服务实例端点又称为会话标识符不同)。
TCP套接字不是连接,它是特定连接的端点。
可以存在与服务端点的并发连接,因为连接由其本地端点和远程端点标识,从而允许将流量路由到特定的服务实例。
对于给定的地址/端口组合,只能有一个侦听器套接字。
展览会
这是一个有趣的问题,迫使我重新审视我以为内在的一些事情。我们会认为" socket"之类的名字是不言而喻的:显然,它被选择为唤起我们插入网络电缆的端点的图像,因为它们具有强大的功能并行性。然而,用网络术语来说,"套接字"一词携带了如此多的行李,因此有必要进行仔细的重新检查。
从最广泛的意义上讲,端口是入口或者出口。尽管未在网络环境中使用,但法语单词porte的字面意思是门或者网关,进一步强调了以下事实:无论是运输数据还是运输大型钢制集装箱,港口都是运输的终点。
出于讨论的目的,我将考虑限制在TCP-IP网络的上下文中。 OSI模型非常好,但尚未完全实现,在高流量高应力条件下的部署范围要小得多。
IP地址和端口的组合严格称为终结点,有时也称为套接字。这种用法源自原始的TCP规范RFC793.
TCP连接由两个端点(即套接字)定义。
端点(套接字)由网络地址和端口标识符的组合定义。请注意,地址/端口不能完全识别套接字(稍后将对此进行详细介绍)。
端口的目的是区分给定网络地址上的多个端点。我们可以说端口是虚拟端点。这种虚拟化使单个网络接口上的多个并发连接成为可能。
It is the socket pair (the 4-tuple consisting of the client IP address, client port number, server IP address, and server port number) that specifies the two endpoints that uniquely identifies each TCP connection in an internet. (TCP-IP Illustrated Volume 1, W. Richard Stevens)
在大多数C派生的语言中,TCP连接是使用Socket类实例上的方法建立和操纵的。尽管通常在更高级别的抽象上进行操作(通常是NetworkStream类的实例),但这通常公开对套接字对象的引用。对于程序员而言,此套接字对象似乎代表连接,因为使用套接字对象的方法创建和操纵了连接。
在C#中,首先要建立TCP连接(到现有侦听器),请创建一个TcpClient。如果我们没有为TcpClient构造函数指定终结点,则它将以一种或者另一种方式使用默认值来定义本地终结点。然后我们调用连接
我们创建的实例上的方法。此方法需要一个描述另一个端点的参数。
所有这些都使我们感到困惑,并使我们相信套接字是一个连接,这是个错误。我一直在这种误解之下努力,直到理查德·多曼(Richard Dorman)问了这个问题。
经过大量的阅读和思考,我现在深信使用类TcpConnection的构造函数接受两个参数LocalEndpoint和RemoteEndpoint会更有意义。当本地端点可接受默认值时,我们可能支持单个参数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不相信我(请参阅评论),所以这是一个真实的样本。我将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的误解是由于我非常小心地使用" identities"一词引起的。我的意思是"完全,明确且唯一地标识"。在上面的示例中,有两个端点的地址/端口组合为" 54.252.94.236:80"。如果我们所拥有的只是地址和端口,那么我们将没有足够的信息来区分这些套接字。尚不足以标识套接字。
附录
RFC793的第2.7节第二段说
A connection is fully specified by the pair of sockets at the ends. A local socket may participate in many connections to different foreign sockets.
从编程的角度来看,此套接字定义没有帮助,因为它与套接字对象不同,后者是特定连接的端点。对于程序员来说,这个问题的大多数受众是程序员,这是至关重要的功能差异。
参考
- TCP-IP图解第1卷,协议,W。理查德·史蒂文斯(W. Richard Stevens),1994年艾迪生·韦斯利(Addison Wesley)
- RFC793,南加州大学信息科学研究所,DARPA
- RFC147,套接字的定义,林肯实验室Joel M. Winett
似乎有很多答案将插座与2台PC之间的连接等同起来。我认为这是绝对不正确的。套接字一直是1台PC上的终结点,可以肯定可以连接也可以不连接,在某些时候我们都使用了侦听器或者UDP套接字*。重要的是它是可寻址且活跃的。向1.1.1.1:1234发送消息不太可能,因为没有为该端点定义套接字。
套接字是特定于协议的,因此TCP / IP和UDP / IP都使用*(ipaddress:port)的唯一性实现与IPX(网络,节点和... ahem套接字)不同,但与套接字不同是指一般的"套接字"一词。IPX套接字号等同于IP端口)。但是,它们都提供了唯一的可寻址端点。
由于IP已成为主要协议,因此端口(就网络而言)已与UDP或者TCP端口号(该套接字地址的一部分)同义。
- UDP是无连接的 - 意味着2个端点被创建过之间没有虚电路。但是,我们仍然将UDP套接字称为端点。 API函数清楚地表明两者都是不同类型的套接字-" SOCK_DGRAM"是UDP(仅发送消息),而" SOCK_STREAM"是TCP(创建虚拟电路)。
- 从技术上讲,IP标头保存IP地址,而IP之上的协议(UDP或者TCP)保存端口号。这样就可以使用其他协议(例如,没有端口号但具有IP地址信息的ICMP)。
从广义上讲,
插座就是一个插座,就像电源,电缆或者电话插座一样。 "必需的东西"(电源,信号,信息)可以进出的地方。它隐藏了许多详细的资料,而使用"必需的资料"并不需要这些资料。用软件的话来说,它提供了一种定义两个实体之间的通信机制的通用方法(这些实体可以是两个应用程序,两个物理上分开的设备,操作系统内的用户和内核空间等)。
端口是端点识别符。它将一个端点与另一个端点区分开。在网络级别,它将一个应用程序与另一个应用程序区分开,以便网络堆栈可以将信息传递给适当的应用程序。
提供了用于本地地址+本地端口+对等地址+对等端口的连接套接字(fd)。通过套接字摘要处理接收/发送数据。
提供了用于本地地址+本地侦听端口的侦听套接字(fd)。进程可以通过套接字接受新的连接。