【问题标题】:Autodetect IP address of Rhode and Schwarz oscilloscope自动检测罗德与施瓦茨示波器的 IP 地址
【发布时间】:2021-10-04 14:55:51
【问题描述】:

我正在尝试编写一个 python 代码,该代码将自动检测罗德和施瓦茨示波器的 IP 地址或使用以太网连接到我的笔记本电脑的任何测试设备。

我工作场所的 R&S 示波器的 IP 地址始终以相同的两个数字 169.254.XX 开头,但诀窍是示波器的 IP 地址仅在我使用它访问示波器时才会出现在 arp -a 报告中我的浏览器中的IP地址。之后 IP 显示在 arp 报告中,但之前 IP 地址不存在。

所以我编写了以下代码,认为它可以工作,但由于在浏览器的 URL 栏中键入 IP 地址之前没有显示 IP 地址,因此它没有工作。 我的目标是通过单击计算机上的一个按钮来确定示波器的 IP 地址,而不是点击示波器的触摸屏来找出设备的 IP。

import tkinter as tk
import time
import threading
import queue
import subprocess

root = tk.Tk()
root.title("SCPI test")
canvas1 = tk.Canvas(root, width=200, height=140, bg='lightsteelblue2', relief='raised')
canvas1.pack()

q1 = queue.Queue()
q2 = queue.Queue()


def auto_detect_ip(num1, num2, num3, num4):
    ping_list = []
    ping_ok_list = []
    t1 = time.time()
    for i in range(num1, num2, -1):
        for j in range(num3, num4, -1):
            temp = "169.254." + str(i) + "." + str(j)
            # temp = "192.168.1.1"
            try:
                p = subprocess.run(["ping", "-n", "1", temp], stdout=subprocess.PIPE, timeout=float(timeout_value))
                # p = subprocess.run(["ping", "-n", "1", temp], stdout=subprocess.PIPE, timeout=0.006)
                return_code = p.returncode
                print("return_code :", return_code)
                if return_code == 0:
                    print("ip_address :", temp)
                    ping_ok_list.append(temp)
                    break
            except subprocess.TimeoutExpired:
                pass
            time.sleep(0.00001)
        else:
            continue
        break
    len_list_ping = len(ping_list)
    print("len_list_ping :", len_list_ping)
    print("ping_ok_list :", ping_ok_list)
    t2 = time.time()
    print("time :", t2 - t1)
    if num4 == 0:
        q1.put(ping_ok_list)
    else:
        q2.put(ping_ok_list) 


def launch_thread():
    print("scan running")
    thread_1 = threading.Thread(target=auto_detect_ip, args=(254, 0, 128, 0))
    thread_2 = threading.Thread(target=auto_detect_ip, args=(254, 0, 254, 128))
    thread_1.setDaemon(True)
    thread_2.setDaemon(True)
    thread_1.start()
    thread_2.start()


def found_rs_scope():
    launch_thread()
    ping_ok_list = q1.get() + q2.get
    print("IP_list :", ping_ok_list)

我的解决方案是扫描每个 IP 地址以查找范围一,但由于在通过浏览器访问范围之前,该 IP 没有出现在提示中的 arp -a 中。 所以在扫描过程中没有匹配,也没有找到 IP。 我认为这应该是可行的,但我只是不知道该怎么做。 此外,我希望能够在不需要管理员权限的情况下找到范围的 IP 地址。

编辑: 我检查了示波器使用的端口,正如 bfris 在他的回答中提到的那样,它是 5025。

【问题讨论】:

  • 是否有机会从名称中找到 IP 地址?来自pingnslookup

标签: python ip-address oscilloscope


【解决方案1】:

我尝试了以下代码但没有成功:

import socket
import tkinter as tk

root = tk.Tk()
root.title("R&S IP finder")
canvas1 = tk.Canvas(root, width=200, height=80, bg='lightsteelblue2', relief='raised')
canvas1.pack()


def ip_finder():
    part1 = 169
    part2 = 254
    port = 5025
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket.setdefaulttimeout(.01)
    sock.settimeout(.01)
    print("starting scan on port {}".format(port))
    for part3 in range(1, 254 + 1):
        for part4 in range(1, 254 + 1):
            ip_address = f'{part1}.{part2}.{part3}.{part4}'
            # print(ip_address)
            result = sock.connect_ex((ip_address, port))
            if result == 0:
                print(ip_address)
                break
            else:
                continue
    print("scan finished.")
    sock.close()


Launch_prgm = tk.Button(text="Device detect", command=ip_finder, bg='green', fg='white', font=('helvetica', 12, 'bold'))
canvas1.create_window(100, 35, window=Launch_prgm)
root.mainloop()

这是在我的笔记本电脑上运行的代码的输出,它连接到示波器(罗德和施瓦茨),我想在浏览器中键入 IP 以控制示波器或在示波器界面本身中找到它之前找到它.

显然,如果结果 == 0: 的条件永远不会为真。 我想我需要管理员权限才能做我想做的事。那就太可惜了。

【讨论】:

  • Web 界面是否侦听端口 80 或 5025?如果它在 80 上侦听,您可以尝试扫描该端口。这可能会证明存在某种 Windows 安全问题的理论。另外,如果你打开Device Identication 选项会发生什么?这看起来很有希望....最后,您可以在范围上寻找一个设置,以始终打开远程接口。
【解决方案2】:

端口扫描器怎么样?在您的情况下,您可能只关心一个端口(我发现了一个侦听 5025 的 R&S Oscope)。但最多 65536 个 IP 地址。如果您能够连接到正确的端口,那么您可能想要做一个 *IDN?查询它是否真的是正确的乐器。

不过这会很慢。你有很多地址要扫描。我将超时设置为 0.01 秒,因此扫描所有地址需要 10 多分钟。我什至不知道 0.010 是否是合法超时。

您可以考虑要求您的 IT 部门根据 MA​​CID 为您的范围分配一个准静态地址。这可能是最快的解决方案。

import socket
import sys

part1 = 169
part2 = 254

port = 5025

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.setdefaulttimeout(.01)
sock.settimeout(.01)

for part3 in range(1,254+1):
    for part4 in range(1,254+1):
        IP = f'{part1}.{part2}.{part3}.{part4}'
        result = sock.connect_ex((IP, port))
        if result == 0:
            print(f'found open port {port} at {IP}')
            # add additional code here to verify
            # it's the right instrument
            
            # also, probably add break to get out of loop
            # if you found the right instrument
            #
            # break
        else:
            print('nothing at ', IP)
        sock.close()

【讨论】:

  • 好的,感谢您的回答和信息。我会试一试,看看它是否符合我的要求。我希望它可以在没有管理员权限的情况下运行。如果我的范围没有在端口 5025 上侦听,那么我猜我可以添加一个循环来循环。
  • 我还在你的代码 sn-p 中注意到你导入了 sys,但是当我在 PyCharm 中运行此代码时,它显示未使用的 sys 导入。这里导入sys的目的是什么?
  • 我看到了一张截图,其中示波器显示了它在 Web 界面上的端口。所以也许你可以仔细检查一下。我不知道端口扫描是最好的解决方案。它很慢。 arp 不能正常工作真是太可惜了。也许还有另一个命令用于询问 Windows DNS 服务器。
  • import sys 实际上是未使用的。我在想我可以使用sys.exit() 来停止脚本,但没有必要。
  • 谢谢,我添加了一个简单的对话框提示来询问代码中的端口号,这样我就可以适应范围使用的任何端口号。我会在今天早上的工作中看看情况如何。
猜你喜欢
  • 1970-01-01
  • 2011-06-08
  • 2014-11-20
  • 2015-06-15
  • 2010-10-10
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 2022-03-03
相关资源
最近更新 更多