在端口和套接字之间混淆

时间:2014-08-18 05:43:14

标签: networking port ip-address

好的,当我尝试研究IP地址,端口和套接字时,这就是我从中得到的:

IP地址用于通过网络映射到不同的设备。

端口号用于访问主机上的特定应用程序。

套接字是两者的组合..

我不明白的是,如果端口将您连接到特定应用程序,那么每个应用程序应该只有1个端口号吗?但是,例如端口80用于HTTP,因此如果应用程序正在使用该端口,它正在侦听HTTP请求吗?那么如果不止一个人试图访问它会发生什么呢?套接字和端口让我很困惑..

3 个答案:

答案 0 :(得分:3)

套接字是软件中使用的抽象,使程序员更容易通过网络发送和接收数据。它们是您在应用程序级代码中使用的接口,用于访问操作系统和语言运行时提供的底层网络协议实现。

TCP协议,IP协议和其他流行的网络协议本身本身,具有"套接字"的任何概念。 "插座和#34;是TCP / IP的实现者的概念。

那么" socket"的概念是什么?基本上,您可以将数据写入和读取数据的对象。 "开放"套接字意味着在程序的内存中创建其中一个对象。你也可以"关闭"套接字,意味着释放该对象在幕后使用的任何系统资源。

某些类型的套接字可以被绑定"到本地和远程地址,您可以将其视为在套接字对象上设置一些数据字段或属性。这些字段的值会影响您在读取或写入套接字时发生的情况。

在Unix中,有各种各样的套接字。如果你打开" TCP套接字," bind"它到本地和远程地址(和端口),并将一些数据写入其中,您的库/操作系统会将数据打包到TCP段中,并通过与您绑定的本地地址相匹配的任何网络接口发送出去。 #34;插座到。如果你打开"一个 IP套接字,并向其写入一些数据,这些数据将打包成一个IP数据包(没有任何添加的TCP头)并发送出去。如果您打开"原始",链接级别套接字并写入,则数据将作为链接级别帧的有效负载发送出去,减去IP TCP标头。还有" Unix域套接字" 。如果你打开其中一个并写入它,数据将直接通过系统内存传递到同一台机器上的另一个进程。

因此,虽然它们经常用于像C这样的非OO语言,但是套接字是OO语言所称的多态性"的完美例子。如果你无法解释什么"多态性"是对某人,只是教他们网络套接字。

"港口"是一个完全不同的概念。 " ports"的想法是内置在中的TCP和其他传输协议。

其他人可能会给出更高的falutin',或许更技术上准确的定义" port"。这是一个完全脚踏实地的人:

A" port"是一个数字,它出现在TCP网段的TCP标头中。 (或UDP段上的UDP头。)

只是一个数字。没什么,没什么。

如果您使用基于" socket"的接口进行网络编程,则该数字的重要性在于您的每个TCP或UDP套接字都有一个"本地端口"财产和远程端口"属性。正如我之前所说,设置这些属性称为"绑定"。

如果您的套接字"本地端口"财产是"绑定"到80,然后你发出的所有TCP段都会有#34; 80"在"发送端口"头。然后,当其他人回复你的消息时,他们会把" 80"在他们的目的地港口"头。

更重要的是,如果您的套接字是"绑定"到本地端口80,然后当数据从其他地方到达,发送到您的端口80时,操作系统会将其传递给您的应用程序进程而不是任何其他进程。然后,当您尝试从套接字读取时,将返回该数据。

显然,操作系统需要知道每个套接字绑定到哪个端口。所以当"绑定"时,必须进行系统调用。如果您的程序没有以足够的权限运行,操作系统可能拒绝让您绑定到某个端口。然后,根据您使用的语言,您的网络库将抛出异常,或返回错误代码。

有时操作系统可能拒绝让您绑定到某个端口,这不是因为您没有权限,而是因为另一个进程已经绑定到它。 然而,这是其他一些答案出错的地方,如果在打开套接字时设置了某些标志,那么您的操作系统可能允许多个套接字绑定到相同的本地地址和端口。

你仍然不知道"倾听"和#34;连接"插座是。但是一旦你理解了上述内容,那只会是一个小小的跳跃。

以上解释了我们今天称之为" socket"我们称之为" port"。可能还不清楚的是:为什么我们需要做出这种区分?

你真的让我想到这里(谢谢)!我们可以将软件抽象称为" socket" a" port"相反,这样您就可以拨打socket_recv而不是拨打port_recv

如果您只对TCP和UDP感兴趣,可能可以使用。请记住," socket"抽象不仅适用于TCP和UDP。它也适用于其他网络协议,以及同一台机器上的进程间通信。

然后,TCP套接字不仅映射到端口。 A"连接" TCP套接字映射到本地IP地址,本地端口,远程地址,远程端口。 还有其他相关数据,包括各种标志,发送和接收缓冲区,输入/输出数据流的序列号,以及用于拥塞控制(速率限制)等的各种其他变量。 只属于本地端口。

可以有数千个TCP连接同时通过相同的"端口"。每个连接都有自己的关联数据,封装每个连接数据的软件对象是一个" TCP套接字"。

即使您只使用TCP / UDP,即使您一次只使用任何给定本地端口的单个进程,即使您一次只有一个连接通过每个本地端口,我认为" socket"抽象仍然是有道理的。如果我们只是调用套接字" ports",那么在这个单词中会有更多含义。重复使用相同的词语会影响沟通。

"港口"是应用程序进程的传输协议级别标识符。 "插座和#34;是软件中用于发送/接收从这些标识符寻址的消息的对象。

区分"我的地址"和#34;发送来自我的信件#34;是一个有用的区别。 "我的地址"只是一个标签。标签不是活动的东西,它可以用来发送数据。给出"用于发送数据的东西是合乎逻辑的。它自己的名称,不同于表示"数据标有"的发件人地址。

答案 1 :(得分:0)

当应用程序(比如像Apache或Nginx这样的Web服务器)正在侦听端口80时,它会创建所谓的侦听套接字。

当某个客户端到来时,这个侦听套接字会得到更新(可以通过selectpoll API注意到),我们的应用程序会创建通信套接字。此套接字由元组(src_addr, src_port, dst_addr, dst_port)唯一标识 - 很多客户端很可能具有完全相同的(dst_addr,dst_port)组合。

然后我们的Web服务器可以通过该通信套接字进行通信,以提供说网页并最终关闭此套接字。当许多客户端并行时,Web服务器可以为每个客户端创建线程/进程(Apache模型),也可以逐个服务所有套接字(Nginx模型)。

请注意,在这种情况下,每个端口只能存在一个侦听套接字 - 多个应用程序无法绑定到80之类的相同端口。但是,拥有多个通信套接字是完全可以的(有些人报告成功同时服务超过一百万个请求)。

答案 2 :(得分:0)

每次在侦听状态上接受套接字连接时(例如,在端口80上),您将在已建立状态下获得套接字表示连接。

在客户端,每次使用该地址和端口建立新连接(正在连接的新套接字)时,操作系统都会为您分配一个随机端口。

例如,如果您连接两次:

your-host:22482 <---> remote-host:80
your-host:23366 <---> remote-host:80