系统相关
首页 > 系统相关> > linux-TCPv4源端口和目标端口可以相互冲突吗?还是源端口和目标端口位于自己的地址空间中?

linux-TCPv4源端口和目标端口可以相互冲突吗?还是源端口和目标端口位于自己的地址空间中?

作者:互联网

让我用一个例子来更具体地说明我的问题:假设我有很多小型服务器,它们全部使用TCPv4在不同的端口上启动.当然,这些端口将成为目标端口.让我们进一步假设这些小型服务器不仅像典型服务器那样在启动时启动,而是根据需求动态地变动.它们会在需要时启动,并且可能会关闭一段时间,然后再重新启动.

现在假设在同一台计算机上,我们还有许多客户端进程通过TCPv4向其他计算机上的服务器进程发出请求.当客户端发出这样的请求时,操作系统会为其分配源端口.

假设出于本示例的考虑,客户端进程向运行在另一台计算机上的RESTful服务器发出Web请求.我们还假设操作系统为此请求分配的源端口是端口7777.

对于此示例,我们还要说,尽管上述请求仍在发生,但我们的一台小型服务器希望启动,并且希望在目标端口7777上启动.

我的问题是这会引起冲突吗?即,由于端口7777已被使用,服务器会收到错误消息吗?还是因为这两种不同类型的端口位于不相互冲突的不同地址空间中,一切都会好吗?

我担心这里可能发生冲突的原因之一是,我看到网页上说“临时源端口选择”通常是在一个相对较高的端口号范围内进行的.这是一个网页:

https://www.cymru.com/jtk/misc/ephemeralports.html

源端口为什么要从高数量开始而不是仅从1开始的一个自然假设是,避免与服务器进程使用的目标端口冲突.尽管我还没有看到任何明确显示出来的东西,并说是这种情况.

附言当然,在此问题上,TCPv4协议规范必须说的是什么,以及操作系统实际上在做什么.例如,也许协议是不可知的,但是OS往往只使用单个地址空间?还是不同的操作系统以不同的方式对待问题?

就个人而言,目前我对Linux的功能最感兴趣.

解决方法:

TCP规范说连接由元组标识:

{local addr, local port, remote addr, remote port}

基于此,理论上,在现有连接中使用的本地端口与尝试将同一端口绑定以供服务器侦听之间不应存在冲突,因为侦听套接字没有远程地址/端口(这些在规范中以通配符表示).

但是,大多数TCP实现(包括Unix套接字API)都比这更严格.如果本地端口已在任何现有套接字中使用,则将无法绑定该端口,您将收到错误EADDRINUSE.如果现有套接字都都处于TIME_WAIT状态,并且新套接字具有SO_REUSEADDR套接字选项,则会发生特殊异常;否则,将发生特殊异常.这用于允许服务器重新启动,而上一个进程留下的套接字仍在等待超时.

因此,端口范围通常分为用途不同的范围.当套接字不绑定本地端口时(要么是因为它只是调用connect()而不调用bind(),要么是通过将IPPORT_ANY指定为bind()中的端口),所以该端口是从临时范围中选择的,通常是编号很高的端口.另一方面,服务器应绑定到低编号的端口.如果网络应用程序遵循此约定,则不应发生冲突.

标签:tcp,unix,network-programming,linux
来源: https://codeday.me/bug/20191211/2106799.html