如何确定源端口以及如何强制它使用特定端口

The*_*ron 32 networking tcp port

当我连接到https://www.google.co.uk 时,它会更改为 216.58.198.228:443。然后在 [My IP Address]:63998 上打开与我的连接。

我的问题是如何选择 63998 端口,是否有办法将其强制为 63999。

Dav*_*ill 43

如何确定本地端口

端口号由 TCP 实现软件从称为临时端口的端口号范围中选择。

选择要使用的端口号和范围的确切机制取决于操作系统。


有没有办法强制它是 63999。

这可以通过更改 TCP 实现软件的配置来完成。

有关为各种不同操作系统配置临时端口范围的说明,请参见更改临时端口范围

  • Linux 和 Windows 的说明包含在下面的这个答案中以供参考。

但是,将范围限制为单个端口并不是一个好主意,例如63999

  • 事实上,在 Windows 上这是不可能的,因为:

    可设置的最小端口范围为 255。


临时端口范围

一个 TCP/IPv4 连接由两个端点组成,每个端点由一个 IP 地址和一个端口号组成。因此,当客户端用户连接到服务器计算机时,建立的连接可以被认为是(服务器IP、服务器端口、客户端IP、客户端端口)的四元组。

通常这四个中的三个是显而易见的——客户端机器使用自己的 IP 地址,当连接到远程服务时,服务器机器的 IP 地址和服务端口号是必需的。

不是很明显的是,当建立连接时,连接的客户端使用端口号。除非客户端程序明确请求特定端口号,否则使用的端口号是临时端口号。

临时端口是由机器的 IP 堆栈分配的临时端口,并且为此目的从指定的端口范围分配。当连接终止时,临时端口可用于重用,尽管大多数 IP 堆栈在整个临时端口池都被使用之前不会重用该端口号。

因此,如果客户端程序重新连接,将为新连接的一侧分配一个不同的临时端口号。

临时端口范围


更改临时端口范围

Linux:

Linux 允许您通过简单地使用文件来查看和更改临时端口范围/proc/sys/net/ipv4/ip_local_port_range。例如,这显示了内核 2.2 系统上的默认配置:

$ cat /proc/sys/net/ipv4/ip_local_port_range 
1024 4999
Run Code Online (Sandbox Code Playgroud)

要将其更改为首选范围,您可以(作为超级用户)执行以下操作:

# echo "49152 65535" > /proc/sys/net/ipv4/ip_local_port_range 
Run Code Online (Sandbox Code Playgroud)

请注意,每次系统启动时您都需要执行此操作,因此请务必在系统启动脚本中添加一行,/etc/rc.local 以便始终使用您的范围。

另请注意,如果有足够的内核内存可用,Linux 2.4 内核将默认范围为 32768 到 61000,因此在较新的 Linux 系统上可能不需要更改范围。

最后,还请注意,您可以使用sysctl界面来更改设置,而不是使用/proc文件系统。sysctl参数名称为“net.ipv4.ip_local_port_range”。/etc/sysctl.conf如果您拥有该文件,请对其进行编辑,或者sysctl如果您想使用sysctl.

Windows Vista/Windows Server 2008 及更新版本:

根据 Microsoft 知识库文章929851,从 Windows Vista 和 Windows Server 2008 开始,Windows 现在默认使用大范围 (49152-65535) 。同一篇文章还展示了如何根据需要更改范围,但默认范围现在对于大多数服务器来说已经足够了。

更改临时端口范围的

您可以使用以下netsh命令查看运行 Windows Vista 或 Windows Server 2008 计算机的计算机上的动态端口范围 :

netsh int ipv4 show dynamicport tcp
netsh int ipv4 show dynamicport udp
netsh int ipv6 show dynamicport tcp
netsh int ipv6 show dynamicport udp 
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 范围是为每个传输和每个 IP 版本单独设置的。
  • 端口范围现在真正是一个具有起点和终点的范围。
  • 如果在内部网络上使用防火墙,部署运行 Windows Server 2008 的服务器的 Microsoft 客户可能会遇到服务器之间的 RPC 通信问题。
  • 在这些情况下,我们建议您重新配置防火墙以允许动态端口范围内的服务器之间的流量49152 通过65535
  • 此范围是对服务和应用程序使用的知名端口的补充。
  • 或者,可以在每台服务器上修改服务器使用的端口范围。

您可以使用netsh命令调整此范围,如下所示:

netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range
Run Code Online (Sandbox Code Playgroud)

此命令设置 TCP 的动态端口范围。起始端口为number,总端口数为range。以下是示例命令:

netsh int ipv4 set dynamicport tcp start=10000 num=1000
netsh int ipv4 set dynamicport udp start=10000 num=1000
netsh int ipv6 set dynamicport tcp start=10000 num=1000
netsh int ipv6 set dynamicport udp start=10000 num=1000
Run Code Online (Sandbox Code Playgroud)

这些示例命令将动态端口范围设置为从端口 10000 开始并在端口10999(1000 个端口)结束。

笔记:

  • 可以设置的最小端口范围是255
  • 可设置的最小起始端口为1025
  • 最大结束端口(基于配置的范围)不能超过65535.
  • 要复制 Windows Server 2003 的默认行为,请1025用作起始端口,然后3976用作 TCP 和 UDP 的范围。这导致 的开始端口1025和结束端口5000

来源 Microsoft 知识库文章929851

Windows XP 及更早版本:

对于较旧的 Windows 操作系统(Windows XP 及更早版本),Windows 使用 1024 到 4999 的传统 BSD 范围作为其临时端口范围。不幸的是,您似乎只能设置临时端口范围的上限。以下信息摘自 Microsoft 知识库文章196271

  • 启动注册表编辑器 ( Regedt32.exe)。
  • 在注册表中找到以下项:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • 在“编辑”菜单上,单击“添加值”,然后添加以下注册表值:

    值名称:MaxUserPort数据类型:REG_DWORD值:(65534例如)

    有效范围:(5000-65534十进制)默认值:0x1388(5000 十进制)

    说明:此参数控制应用程序从系统请求任何可用用户端口时使用的最大端口号。通常情况下,短暂的(也就是短暂)端口的值之间的分配10245000包容性。

  • 退出注册表编辑器。

注意:还有另一篇相关的知识库文章 ( 812873 ) 声称允许您设置排除范围,这可能意味着您可以排除端口1024-9999(例如)以将临时端口范围设为10000-65534. 但是,我们还没有能够让它发挥作用(截至 2004 年 10 月)。

更改临时端口范围的

  • 与其更改临时端口范围,不如让应用程序在调用 `connect` 之前先调用 `bind` 系统调用。某些应用程序可以选择这样做,而其他应用程序则没有。 (2认同)

Mar*_*iae 9

David Postill 的回答是完全正确的。我想补充一点,强调在Linux中更改临时端口范围非常简单,OP 给出了肯定的答案。

您可以按如下方式更改 EPR:

echo "40000 60000" > /proc/sys/net/ipv4/ip_local_port_range 
Run Code Online (Sandbox Code Playgroud)

您可以使用以下脚本选择端口 50000(作为示例):

OLD_RANGE=$(cat /proc/sys/net/ipv4/ip_local_port_range)
MY_PORT=50000
echo "$MY_PORT $MY_PORT" > /proc/sys/net/ipv4/ip_local_port_range
sudo -u SomeUser SomeApplication  & 
echo $OLD_RANGE" > /proc/sys/net/ipv4/ip_local_port_range 
Run Code Online (Sandbox Code Playgroud)

这里有一个警告:由于范围内只有一个端口,另一个应用程序可能会在执行上面的第三行和第四行之间从你那里抢走它;此外,即使没有竞争条件,您也会瘫痪所有其他应用程序,直到您恢复一个大 EPR,这就是我尽快恢复原始范围的原因。

因此,如果OP 的操作系统是 Linux,答案将是它可以轻松完成。

令人惊讶的是,这在 BSD 上并不那么简单,其中一些甚至没有 EPR 的运行时内核设置。MacOS X、FreeBSD 和 OpenBSD 需要修改文件/etc/sysctl.conf,但它们对 EPR 有不同的选择。

不管上述和操作系统如何,可以做某事的事实并不意味着它应该做:你到底为什么需要这个?我想不出一个用例。