Android 客户端发起端口扫描,有什么高效率的办法么 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sodaless
V2EX    Java

Android 客户端发起端口扫描,有什么高效率的办法么

  •  
  •   sodaless
    misakuo 2015-12-31 11:18:36 +08:00 6432 次点击
    这是一个创建于 3573 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一个比较恶心的需求,需要客户端扫描开启了 49494 端口( PhotoShop Server )的 Host ,网络掩码是 255.255.248.0 ,一个子网 2000 多个主机,现在的策略是每 128 个 IP 分配一个线程进行扫描,先判断网络是不是可达,如果可达的话尝试和 49494 端口建立 Socket 连接,连接成功则视为该 Host 开启了 PhotoShop Server 。现在扫描一遍大概耗时 8 秒,感觉还是太慢,并且线程数过多( 16 个),有什么更好的办法么 ToT

    15 条回复    2016-01-18 09:32:46 +08:00
    shepherd
        1
    shepherd  
       2015-12-31 13:14:50 +08:00 via Android
    客户端是要把整个网络里开了端口的机器都扫出来吗?还是只有要扫到可用的 host 就行。如果是发现全部, 2000 多个机器,光 ping 都要好久,在没有辅助方法的情况下,单靠客户端去扫,是肯定要花一些时间的。如果客户端的使用环境比较固定,可以考虑在网络环境中驾一个机器负责扫,客户端只要向该机器获取列表即可。如果不是要发现全部 host ,就优化一下客户端扫描的算法,比如不要按 ip 的顺序扫,考虑做个散列算法什么的随机去扫等等。再不然,研究一下 Photoshop server 的协议,看看有没有什么广播之类的功能,在客户端上处理一下。
    sodaless
        2
    sodaless  
    OP
       2015-12-31 13:24:57 +08:00
    @shepherd 要发现全部,并且因为是园区网络, IP 地址经常变化。目前的问题是整个子网里可达的 IP 地址不多,扫描线程遇到不可达的 IP 时会等待直到达到超时时间后(目前设置了 150ms )才会继续扫描下一个 IP ,和这个端口建立的还必须是 TCP 连接,我也想看看能 PS Server 会不会发广播之类的,目前还没从文档上看到,官方的 sample 和文档也是一团糟
    wu360463231
        3
    wu360463231  
       2015-12-31 13:38:31 +08:00
    能在客户端运行多一个进程吗,可以的话直接写个 UDP 广播接收反馈的。这样每个子网 UDP 广播下就知道哪些主机可用
    sodaless
        4
    sodaless  
    OP
       2015-12-31 13:48:53 +08:00
    @wu360463231 可以多一个进程,在这里 UDP 广播该怎么用?求指教。
    TheCure
        5
    TheCure  
       2015-12-31 13:49:09 +08:00
    为什么要去检查 IP 是否可达啊,直接发个 SYN 包不就行了,反正你们也是独立 IP,一口气发 2000 个 SYN 包,然后看谁回复了 ACK 呗.

    但是这个方法需要用 raw socket 也就是你要有 root 权限,这在安卓上应该不好办.

    我的方法和 1L 一样,找台机器做 relay,机器上装个 zmap,nmap 之类的速度嗖嗖的,然后你去拿列表.

    至于 UDP 广播...园区的路由器是否支持广播都不知道,就算你能广播,也只能扫到一个路由器下的,什么?你要用组播?还是算了吧组播不支持 TCP 的,你还得保证 TCP UDP 端口都同时打开
    zbz
        6
    zbz  
       2015-12-31 14:16:39 +08:00
    创建 N 个 socket ,以非阻塞的方式分别连接到需要验证的<IP, Port>,然后等待 M 秒后检查连接是否成功。

    假设 N 是 1000 , M 是 1 ,那么一秒钟验证 1000 个 IP 毫无压力。
    sodaless
        7
    sodaless  
    OP
       2015-12-31 14:46:11 +08:00
    @zbz Excited !我去试试,只是不知道创建这么多 socket 开销会不会很大
    sodaless
        8
    sodaless  
    OP
       2015-12-31 16:25:47 +08:00
    @zbz 试了下果然效果拔群,有个小问题就是操作太快的话会报“ Host is down ”和“ No route to host ”,不知道是不是被网关给搞了
    zealot0630
        9
    zealot0630  
       2015-12-31 18:33:32 +08:00
    No route to host 是未收到 ARP 回应,很可能是 IP 根本没机器使用
    Host is down 是对面回应了 ARP ,但是没有回应 SYN ,多半是因为开了防火墙
    tobyxdd
        10
    tobyxdd  
       2015-12-31 18:38:37 +08:00
    用 nmap 不行么
    ericyl
        11
    ericyl  
       2015-12-31 20:06:21 +08:00
    我之前的做法是开启 socket 长连接,然后 UDP 循环发送消息,其他机器在接收到 UDP 消息后主动连接 socket
    mengskysama
        12
    mengskysama  
       2015-12-31 20:29:35 +08:00
    一般学校路由或者三层交换都会限制每秒新建连接数,我们这边限制比较死每个终端 200 。。
    gamexg
        13
    gamexg  
       2015-12-31 20:31:48 +08:00 via Android
    很麻烦吗?
    曾经在 vps 上 golang ,开 500 协程扫 google tls ,没发现问题啊。
    LGA1150
        14
    LGA1150  
       2015-12-31 22:22:39 +08:00
    Fing Network Tools - Discover any IP network
    sodaless
        15
    sodaless  
    OP
       2016-01-18 09:32:46 +08:00
    Hi all ,问题已经解决,和大家同步一下 solution , NIO 非阻塞式 socket 是一个挺好的办法,但在移动设备上依然不适用,我测试的安卓机器最多同时打开 1024 个连接后就会达到文件打开数的上限,即使队列式处理,主动关闭 socket 后句柄好像也不能即时释放。并且 socket channel 在 finishConnect 的时候会被阻塞,不知道是不是被路由设备限制了。最后的解决办法是使用 mDNS ,广播方式寻找,在 java 上有 JmDNS 库可以使用,在 Android API 16 以上系统有提供 NsdManager 服务,很好使,完美解决。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5931 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 01:55 PVG 09:55 LAX 18:55 JFK 21:55
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86