Answers:
TCP套接字是在特定TCP连接或侦听状态的上下文中由IP地址和端口定义的终结点实例。
端口是定义服务端点的虚拟化标识符(与服务实例端点又称为会话标识符不同)。
TCP套接字不是连接,它是特定连接的端点。
可以存在到服务端点的并发连接,因为连接由其本地端点和远程端点标识,从而允许将流量路由到特定的服务实例。
对于给定的地址/端口组合,只能有一个侦听器套接字。
这是一个有趣的问题,迫使我重新审视我以为内在的一些事情。您会认为“ socket”之类的名字是不言而喻的:显然,它被选择来唤起插入网络电缆的端点的图像,因为它们具有强大的功能并行性。然而,用网络术语来说,“ socket”一词承载着太多的行李,因此有必要进行仔细的重新检查。
从最广泛的意义上讲,端口是入口或出口。尽管未在网络环境中使用,法语单词porte的字面意思是门或网关,进一步强调了以下事实:无论是运输数据还是运输大型钢制集装箱,港口都是运输的终点。
出于讨论的目的,我将考虑限制在TCP-IP网络的上下文中。OSI模型非常好,但从未完全实现,在高流量高应力条件下的部署范围则要小得多。
IP地址和端口的组合严格称为端点,有时也称为套接字。这种用法源自原始的TCP规范RFC793。
TCP 连接由两个端点(即套接字)定义。
端点(套接字)由网络地址和端口标识符的组合定义。请注意,地址/端口不能完全识别套接字(稍后将对此进行详细介绍)。
端口的目的是区分给定网络地址上的多个端点。您可以说端口是虚拟端点。这种虚拟化使单个网络接口上的多个并发连接成为可能。
套接字对(由客户端IP地址,客户端端口号,服务器IP地址和服务器端口号组成的4元组)指定了两个端点,这些端点唯一地标识了Internet中的每个TCP连接。(TCP-IP图解卷1,W。Richard Stevens)
在大多数C派生的语言中,TCP连接是使用Socket类实例上的方法建立和处理的。尽管通常在更高级别的抽象上进行操作(通常是NetworkStream类的实例),但这通常公开对套接字对象的引用。对于程序员而言,此套接字对象似乎代表连接,因为使用套接字对象的方法创建和操纵了连接。
在C#中,首先要建立TCP连接(到现有侦听器),请创建一个TcpClient。如果未为TcpClient构造函数指定端点,则它将使用默认值-一种或另一种方式定义了本地端点。然后, 在创建的实例上调用Connect方法。此方法需要一个描述另一个端点的参数。
所有这些都使您感到困惑,并使您相信套接字是一个连接,这是个错误。我一直在这种误解之下努力,直到理查德·多曼(Richard Dorman)问了这个问题。
经过大量的阅读和思考,我现在确信拥有类TcpConnection的构造函数接受两个参数LocalEndpoint和RemoteEndpoint会更有意义。当本地端点可接受默认值时,您可能支持单个参数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.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的误解是由于我非常小心地使用了“ identified”一词。我的意思是“完全,明确且唯一地标识”。在以上示例中,有两个端点具有地址/端口组合54.252.94.236:80
。如果仅有地址和端口,则没有足够的信息来区分这些套接字。尚不足以标识套接字。
RFC793的第2.7节第二段说
两端的一对插座完全指定了连接。本地套接字可以参与到不同外部套接字的许多连接。
从编程的角度来看,套接字的这种定义没有帮助,因为它与套接字对象不同,后者是特定连接的端点。对于程序员来说,这个问题的大多数受众都是程序员,这是至关重要的功能差异。
一个套接字包括三件事:
端口是介于1到65535(含)之间的数字,表示设备中的逻辑门。客户端和服务器之间的每个连接都需要一个唯一的套接字。
例如:
套接字表示两个网络应用程序之间的单个连接。这两个应用程序名义上可以在不同的计算机上运行,但是套接字也可以用于单台计算机上的进程间通信。应用程序可以创建多个用于相互通信的套接字。套接字是双向的,这意味着连接的任何一侧都能够发送和接收数据。因此,理论上可以在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
打个比方
尽管上面已经为套接字提供了很多技术资料……我想补充一下我的答案,以防万一,如果有人仍然感觉不到ip,port和sockets之间的区别
考虑服务器S,
并说X,Y,Z人需要来自该服务器S的服务(例如聊天服务)
然后
IP地址告诉 -> 谁?X,Y,Z要联系的聊天服务器“ S”
好的,您得到了“谁是服务器”
但是假设服务器“ S”也在向其他人提供其他服务,例如“ S”向A,B,C人提供存储服务
然后
端口告诉 ---> 哪个?您(X,Y,Z)需要的服务,即聊天服务,而不是该存储服务
好的..,您使服务器知道“聊天服务”是您想要的,而不是存储
但
您是三岁,服务器可能希望以不同的方式标识所有这三个
插座来了
现在套接字告诉 -> 哪一个?特定的联系
也就是说,
X人的插座1
Y人的插座2
Z人的插座3
我希望它可以帮助仍然困惑的人:)
首先,我认为我们应该从对从A到B的数据包的构成的理解开始。
网络的常见定义是使用OSI模型,该模型根据目的将网络分为多个层。有一些重要的问题,我们将在这里介绍:
除其他事项外,TCP包含端口的概念。这些实际上是Internet套接字(AF_INET
)可以绑定到的同一IP地址上的不同数据终结点。
碰巧的是,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);
也有可能。哦,那把东西扔了!
好的,实际上还没有。我们需要做的就是提供一些适当的定义:
/var/run/database.sock
。瞧!那把事情整理了。因此,在我们的方案中,
因此,实际上,端口是形成Internet套接字的要求的一部分。不幸的是,恰好发生了“插座”一词的含义被应用到几种不同的想法。因此,我衷心建议您为下一个项目套接字命名,以免造成混乱;)
套接字= IP地址+端口(数字地址)
它们共同标识了计算机上网络连接的端点。(我刚刚使网络101失效了吗?)
通常,您将获得很多理论知识,但区分这两个概念的最简单方法之一如下:
为了获得服务,您需要一个服务号码。该服务号码称为端口。就那么简单。
例如,HTTP即服务在端口80上运行。
现在,许多人可以请求该服务,并且已经建立了与客户端-服务器的连接。会有很多联系。每个连接代表一个客户端。为了维护每个连接,服务器会为每个连接创建一个套接字以维护其客户端。
似乎有很多答案将插座等同于两台PC之间的连接。我认为这是绝对不正确的。套接字一直是1台PC上的端点,它可以连接也可以不连接-肯定在某个时候我们都使用了监听器或UDP套接字*。重要的是它是可寻址且活跃的。向1.1.1.1:1234发送消息不太可能,因为没有为该端点定义套接字。
套接字是特定于协议的-因此TCP / IP和UDP / IP使用的唯一性实现*(ipaddress:port)与IPX(网络,节点和... ahem,套接字)不同-但有所不同而不是一般的“套接字”一词所表示的IPX套接字号。但是,它们都提供了唯一的可寻址端点。
由于IP已成为主要协议,因此端口(以网络术语而言)已与UDP或TCP端口号(该套接字地址的一部分)同义。
简短简短的回答。
甲端口可以被描述为一个内部地址标识的程序或处理的宿主内。
甲插座可以被描述为一个编程接口,允许一个程序来与其他程序或进程进行通信,在互联网上,或局部。
它们是来自两个不同域的术语:“端口”是TCP / IP网络的概念,“套接字”是API(编程)。通过使用端口和主机名或网络适配器并将它们组合到可用于发送或接收数据的数据结构中,以代码形式形成“套接字”。
这些是基本的网络概念,因此我将以一种简单而全面的方式来解释它们,以详细了解它们。
因此,网络中的套接字是绑定到一对(ip,port)=(address,service)的虚拟通信设备。
注意:
希望它消除您的疑虑
阅读了极好的投票答案后,我发现以下几点需要我强调,这是网络编程的新手:
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
...
123.132.213.231 # IP address
:1234 # port number
123.132.213.231:1234 # socket address
当两个套接字绑定在一起时,就会发生连接。
套接字是一种特殊类型的文件句柄,进程使用它来向操作系统请求网络服务。套接字地址是三元组:{协议,本地地址,本地进程},其中本地进程由端口号标识。
在TCP / IP套件中,例如:
{tcp,193.44.234.3,12345}
对话是两个过程之间的通信链接,因此描述了两个过程之间的关联。关联是5元组,它完全指定了组成连接的两个进程:{协议,本地地址,本地进程,外部地址,外部进程}
在TCP / IP套件中,例如:
{tcp,193.44.234.3,1500,193.44.234.5,21}
可能是有效的关联。
半关联为:{协议,本地地址,本地进程}
要么
{协议,外来地址,外来程序}
指定每个连接的一半。
半关联也称为套接字或传输地址。也就是说,套接字是可以在网络中命名和寻址的通信的端点。套接字接口是通信协议的几种应用程序编程接口(API)之一。它被设计为通用通信编程接口,最初由4.2BSD UNIX系统引入。尽管尚未标准化,但已成为事实上的行业标准。
套接字是通信端点。套接字与TCP / IP协议系列没有直接关系,它可以与系统支持的任何协议一起使用。C套接字API希望您首先从系统中获取一个空白套接字对象,然后可以将其绑定到本地套接字地址(以直接检索无连接协议的传入通信或接受面向连接协议的传入连接请求)或者您可以连接到远程套接字地址(对于任何一种协议)。如果您想同时控制两者,绑定到套接字的本地套接字地址和连接到套接字的远程套接字地址,则可以同时执行这两个操作。对于无连接协议,连接套接字甚至是可选的,但如果不这样做,那么 您还必须将要通过套接字发送的每个数据包都传递目的地地址,否则套接字将如何知道将数据发送至何处?优点是您可以使用单个套接字将数据包发送到不同的套接字地址。一旦配置好套接字,甚至可能将其连接,就将其视为双向通信管道。您可以使用它将数据传递到某个目标,而某些目标可以使用它将数据传递回您。您写给套接字的内容将被发送出去,接收到的内容可被读取。您可以使用它将数据传递到某个目标,而某些目标可以使用它将数据传递回您。您写给套接字的内容将被发送出去,接收到的内容可被读取。您可以使用它将数据传递到某个目标,而某些目标可以使用它将数据传递回您。您写给套接字的内容将被发送出去,接收到的内容可被读取。
另一方面,端口是仅TCP / IP协议栈的某些协议具有的端口。TCP和UDP数据包具有端口。端口只是一个简单的数字。源端口和目标端口的组合标识了两个主机之间的通信通道。例如,您可能拥有同时为简单的HTTP服务器和简单的FTP服务器的服务器。如果现在有到达该服务器地址的数据包,那么它将如何知道这是HTTP还是FTP服务器的数据包?好吧,它将知道HTTP服务器将在端口80上运行,而FTP服务器将在端口21上运行,因此,如果数据包通过目标端口80到达,则该数据包用于HTTP服务器,而不用于FTP服务器。数据包还具有一个源端口,因为如果没有这样的源端口,则服务器一次只能与一个IP地址建立一个连接。源端口使服务器可以区分其他方面相同的连接:它们都具有相同的目标端口,例如端口80,相同的目标IP(服务器的IP)和相同的源IP,因为它们都来自相同的客户端,但是由于它们具有不同的源端口,因此服务器可以将它们彼此区分。当服务器发回答复时,它将发送到请求来自的端口,这样客户端也可以区分从同一服务器收到的不同答复。
端口是最简单的部分,它只是套接字的唯一标识符。套接字是进程可以用来建立连接和相互通信的东西。高个子杰夫有一个很棒的电话类比,这并不完美,所以我决定修复它:
netstat
显示器。从侦听套接字接受的所有套接字共享同一端口。因此,端口不是套接字的唯一标识符。
一个应用程序由一对通过网络进行通信的进程(客户端-服务器对)组成。这些过程通过称为socket的软件接口向网络发送消息和从网络接收消息。考虑一下“计算机网络:自上而下的方法”一书中提出的类比。有一个房子要与其他房子通信。在这里,房屋类似于过程,门类似于插座。发送过程假定门的另一侧有一个基础结构,可以将数据传输到目的地。一旦消息到达另一侧,它就会通过接收者的门(套接字)进入房屋(过程)。同一本书的插图可以帮助您:
套接字是传输层的一部分,它为应用程序提供逻辑通信。这意味着从应用程序的角度来看,即使两台主机之间都存在许多路由器和/或交换机,它们也直接相互连接。因此,套接字本身不是连接,而是连接的终点。传输层协议仅在主机上实现,而不在中间路由器上实现。
港口提供对机器的内部寻址方式。其主要目的是允许多个进程通过网络发送和接收数据,而不会干扰其他进程(它们的数据)。所有插座都提供了端口号。当一个段到达主机时,传输层将检查该段的目标端口号。然后它将段转发到相应的套接字。将传输层段中的数据传递到正确的套接字的这项工作称为多路分解。然后将段的数据转发到附加到套接字的进程。
套接字是软件中的结构。它或多或少是一个文件;它具有读取和写入之类的操作。这不是物理的东西;这是您的软件引用物理事物的一种方式。
端口是类似设备的东西。每个主机都有一个或多个网络(物理网络);主机在每个网络上都有一个地址。每个地址可以具有数千个端口。
一个插座只能使用某个地址的端口。套接字大致为端口分配端口,就像为文件系统I / O分配设备一样。分配端口后,没有其他套接字可以连接到该端口。关闭插座后,端口将释放。
看一看TCP / IP术语。
套接字是网络上运行的两个程序之间双向通讯链接的一个端点。套接字与端口号绑定,以便TCP层可以识别将数据发送到的应用程序。
可以将端口和套接字与银行分行进行比较。
“银行”的建筑物号类似于IP地址。银行有不同的部分,例如:
因此1个(储蓄帐户部门),2个(个人贷款部门),3个(房屋贷款部门)和4个(申诉部门)是港口。
现在,让我们说您去开设一个储蓄帐户,去银行(IP地址),然后去“储蓄帐户部门”(端口号1),然后遇到在“储蓄帐户部门”工作的一名员工”。让我们称他为SAVINGACCOUNT_EMPLOYEE1以开设帐户。
SAVINGACCOUNT_EMPLOYEE1是您的套接字描述符,因此SAVINGACCOUNT_EMPLOYEEN可能有SAVINGACCOUNT_EMPLOYEE1。这些都是套接字描述符。
同样,其他部门也将雇用员工在其下工作,它们类似于套接字。
问题所隐含的是我假设的相对TCP / IP术语。用外行的话来说:
PORT就像是特定邮政编码中特定房屋的电话号码。城镇的邮政编码可以认为是城镇以及该城镇中所有房屋的IP地址。
另一方面,SOCKET更像是一对彼此通话的房屋的电话之间建立的电话。可以在同一城镇的房屋之间或不同城镇的两座房屋之间建立这些呼叫。SOCKET就是这对相互通话的电话之间的临时建立路径。
已经对该问题给出了理论答案。我想为这个问题提供一个实际的例子,这将清除您对Socket和Port的理解。
我在这里找到
本示例将带您完成连接到网站(例如Wiley)的过程。您将打开Web浏览器(例如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套接字。
套接字是内核为用户应用程序提供的用于数据I / O的抽象。套接字类型是由协议的处理方式,IPC通信等定义的。因此,如果有人创建了TCP套接字,他可以通过简单的方法以及较低级别的协议处理(例如TCP转换和将数据包转发到较低级别的网络协议是由内核中的特定套接字实现完成的。优点是用户不必担心处理协议特定的问题,而应该像普通缓冲区一样向套接字读取和写入数据。对于IPC,情况也是如此,用户只需向套接字读取和写入数据,内核便会根据创建的套接字类型处理所有较低级别的详细信息。
与IP一起使用的端口就像为套接字提供地址,尽管它不是必需的,但它有助于网络通信。
单个端口可以具有一个或多个与不同外部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
套接字基本上是网络通信的端点,至少由一个IP地址和一个端口组成。在Java / C#中,套接字是双向连接一侧的高级实现。
另外,Java文档中的定义。
港口:
端口可以指向外围设备(例如串行,并行和USB端口)的物理连接点。术语端口也指某些以太网连接点,例如集线器,交换机或路由器上的那些。
插座:
套接字表示两个网络应用程序之间的单个连接。这两个应用程序名义上可以在不同的计算机上运行,但是套接字也可以用于单台计算机上的进程间通信。应用程序可以创建多个用于相互通信的套接字。套接字是双向的,这意味着连接的任一端都能够发送和接收数据。