【问题标题】:Given an IP address on local linux machine, how check whether it is occuppied?给定本地linux机器上的IP地址,如何检查它是否被占用?
【发布时间】:2022-01-14 20:11:53
【问题描述】:

我知道一个 IP 可以被多个进程使用,但我的用例要求一个 IP 只能由一个进程使用。

我的机器 (ubuntu) 上有多个 IP,并且多个正在运行的进程正在使用这些 IP 作为 tcp 客户端。这些 IP 具有相同的路由设置(公制除外)。每个进程都使用其中一个 IP。问题是我手动分配了哪个进程使用哪个 IP。

我想知道我是否可以使这个过程自动化。当一个进程启动时,它会检查给定的 ip 列表,并使用第一个未被占用的。这可能吗?

【问题讨论】:

  • 这只有在您谈论特定的客户端应用程序时才真正有意义。 Web 浏览器或电子邮件客户端没有理由不能使用与这些应用程序进程之一相同的 IP。

标签: c linux


【解决方案1】:

对于您想要使用的每个可能的 IP,尝试将您的套接字绑定到该 IP 以及所有客户端都将使用的已知端口。如果绑定调用成功,则该套接字将只有一个使用该 IP 和端口。

如果绑定调用失败并返回错误代码EADDRINUSE,您就知道某个其他套接字已绑定到该 IP 和端口。然后您可以尝试列表中的下一个 IP。

【讨论】:

    【解决方案2】:

    设置:使用 5 个 IP 地址创建接口 bridge0

    ip link add name bridge0 type bridge
    ip link set bridge0 up
    ip addr add 192.168.1.5/24 dev bridge0
    ip addr add 192.168.1.6/24 dev bridge0
    ip addr add 192.168.1.7/24 dev bridge0
    ip addr add 192.168.1.8/24 dev bridge0
    ip addr add 192.168.1.9/24 dev bridge0
    

    要查看可用的 IP 地址:

    $ ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether xxxx brd ff:ff:ff:ff:ff:ff
        inet xxxx/24 brd xxxx scope global dynamic noprefixroute wlan0
           valid_lft 299sec preferred_lft 299sec
        inet6 xxxx/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever
    3: bridge0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
        link/ether xxxx brd ff:ff:ff:ff:ff:ff
        inet 192.168.1.5/24 scope global bridge0
           valid_lft forever preferred_lft forever
        inet 192.168.1.6/24 scope global secondary bridge0
           valid_lft forever preferred_lft forever
        inet 192.168.1.7/24 scope global secondary bridge0
           valid_lft forever preferred_lft forever
        inet 192.168.1.8/24 scope global secondary bridge0
           valid_lft forever preferred_lft forever
        inet 192.168.1.9/24 scope global secondary bridge0
           valid_lft forever preferred_lft forever
        inet6 fe80::6c8e:f0ff:fe1f:6779/64 scope link 
           valid_lft forever preferred_lft forever
    

    仅获取可用的 IP 地址:

    $ ip addr | grep inet | grep bridge0
        inet 192.168.1.5/24 scope global bridge0
        inet 192.168.1.6/24 scope global secondary bridge0
        inet 192.168.1.7/24 scope global secondary bridge0
        inet 192.168.1.8/24 scope global secondary bridge0
        inet 192.168.1.9/24 scope global secondary bridge0
    

    或:

    $ ip addr | grep inet | grep bridge0 | awk '{print $2}'
    192.168.1.5/24
    192.168.1.6/24
    192.168.1.7/24
    192.168.1.8/24
    192.168.1.9/24
    

    然后你可以使用ss查看使用的是哪个端口:

    $ ss -ltn
    State        Recv-Q       Send-Q             Local Address:Port               Peer Address:Port       Process       
    LISTEN       0            80                       0.0.0.0:3306                    0.0.0.0:*                        
    LISTEN       0            128                      0.0.0.0:22                      0.0.0.0:*                        
    LISTEN       0            5                      127.0.0.1:52698                   0.0.0.0:*                        
    LISTEN       0            80                          [::]:3306                       [::]:*                        
    LISTEN       0            511                            *:80                            *:*                        
    LISTEN       0            50                             *:1716                          *:*                        
    LISTEN       0            128                         [::]:22                         [::]:*                        
    LISTEN       0            256                            *:3128                          *:*
    

    或:

    $ ss -ltn | awk '{print $4}'
    Local
    0.0.0.0:3306
    0.0.0.0:22
    127.0.0.1:52698
    [::]:3306
    *:80
    *:1716
    [::]:22
    *:3128
    

    然后你可以解析输出来决定哪个端口还没有使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-20
      • 2011-09-10
      • 2017-05-28
      • 1970-01-01
      • 2016-08-28
      • 2013-11-27
      • 2017-10-30
      • 2016-08-12
      相关资源
      最近更新 更多