动态获取树莓派的变动外网ip

本文介绍了一个简单的Python脚本,用于定期检查本地IP地址的变化,并在IP发生变化时通过邮件通知管理员。该脚本利用了定时任务和SMTP服务实现。

ip变化时发邮件通知

在此目录下创建 /home/config.py 配置邮箱信息

#!/usr/bin/env python
#-*-coding:utf-8-*-
smtpServer='smtp.126.com' #邮件发送帐户的smtp服务器地址
smtpPort='25' #邮件发送帐户的smtp服务器发送端口
smtpUser='xxxxx@126.com' #邮件发送帐户名
smtpPwd='xxxx' #邮件发送帐户密码,我这里打X号示例,但老兄得填真的
sendTo='xxxx@163.com' #接收邮箱地址

在此目录下创建 /home/sendIP.py脚本 负责检查发送。
然后在/etc/rc.local里加上下面这行
/usr/bin/python /home/sendIP.py 启动时运行
代码如下

#!/usr/bin/env python
#-*-coding:utf-8-*-
import smtplib,config,email,sys,socket,threading
from email.Message import Message
import re,urllib2

class Getmyip:
        def getip(self):
                try:
                        myip = self.visit("http://www.whereismyip.com/")
#                   return myip
                except:
                        try:
                                myip = self.visit("http://www.bliao.com/ip.phtml")
#                           return myip
                        except:
                                try:
                                        myip = self.visit("http://www.whereismyip.com/")
#                                   return myip
                                except:
                                        myip = "So sorry!!!"
                return myip

        def visit(self,url):
                opener = urllib2.urlopen(url)
                if url == opener.geturl():
                        str = opener.read()
#                        print str
                        asd=re.search('\d+\.\d+\.\d+\.\d+',str).group(0)
                        return asd

def connect():
        try:
                server=smtplib.SMTP(config.smtpServer,config.smtpPort)
                server.ehlo()
                server.login(config.smtpUser,config.smtpPwd)
                return server
        except Exception:
                print 'connect smtp server failed!'

def sendmessage(server,to,subj,content):
        msg = Message()
        msg['Mime-Version']='1.0'
        msg['From']        = config.smtpUser
        msg['To']          = to
        msg['Subject'] = subj
        msg.set_payload(content)
        try:        
                failed = server.sendmail(config.smtpUser,to,str(msg))
        except Exception ,ex:
                print Exception,ex
                print 'Error - send failed'
        else:
                print 'send succeed!'

#每隔10s检查一次IP,间隔时间可以适当调大一点
def checkIP():
        global text
        #getmyip = Getmyip()
        print text
        ipnow=getmyip.getip()
        print ipnow
        if  text!=ipnow:
                text=ipnow
                server=connect()
                sendmessage(server,to,subj,text)
        t = threading.Timer(600.0, checkIP)
        t.start()

if __name__=="__main__":
        getmyip = Getmyip()
        to=config.sendTo
        subj='ip changed' 
        text = getmyip.getip() #这个就是获取本机IP的
        server=connect()
        sendmessage(server,to,subj,text)
        t = threading.Timer(600.0, checkIP)
        t.start()
<think>我们正在使用QT框架开发运行在树莓派上的应用程序,需要获取树莓派本机的IP地址。 根据引用[1],我们可以通过扫描局域网来获取树莓派IP地址,但这通常是在外部设备(如手机)上进行的操作。而在QT应用程序内部,我们需要直接获取本机IP地址。 引用[2]提供了一个QT函数`getLocalIp()`,该函数通过`QNetworkInterface::allAddresses()`获取所有网络接口的地址列表,然后遍历列表找到第一个非本地回环地址且是IPv4地址的地址。 因此,我们可以采用类似的方法在树莓派上使用QT获取本机IP地址。 步骤: 1. 包含必要的头文件:`<QNetworkInterface>`和`<QHostAddress>`。 2. 遍历`QNetworkInterface::allAddresses()`返回的地址列表。 3. 跳过回环地址(即`QHostAddress::LocalHost`,通常为127.0.0.1),并检查地址是否为IPv4地址(使用`toIPv4Address()`方法,非0即为IPv4地址)。 4. 返回找到的第一个符合条件的IPv4地址。如果没找到,则返回本地回环地址。 注意:树莓派可能有多个网络接口(如eth0有线网卡、wlan0无线网卡),上述方法返回的是第一个非回环的IPv4地址。如果需要获取特定接口的IP地址,则需要通过`QNetworkInterface`获取指定接口的地址列表。 下面是一个示例函数,用于获取本机第一个非回环的IPv4地址: ```cpp #include <QHostAddress> #include <QNetworkInterface> QString getLocalIp() { // 获取所有网络接口的IP地址列表 QList<QHostAddress> ipList = QNetworkInterface::allAddresses(); for (const QHostAddress &address : qAsConst(ipList)) { // 跳过回环地址和IPv6地址(注意:toIPv4Address()在IPv6地址上返回0) if (address != QHostAddress::LocalHost && address.toIPv4Address()) { return address.toString(); } } // 如果没有找到,则返回本地回环地址 return QHostAddress(QHostAddress::LocalHost).toString(); } ``` 注意:上述代码遍历所有地址,返回第一个符合条件的地址。在实际使用中,树莓派可能有多个网络接口(例如同时连接有线和无线网络),因此可能需要根据具体需求选择特定的网络接口。 如果需要获取特定网络接口(例如eth0)的IP地址,可以修改函数如下: ```cpp QString getInterfaceIp(const QString &interfaceName) { QNetworkInterface interface = QNetworkInterface::interfaceFromName(interfaceName); if (!interface.isValid()) { // 接口无效,返回空字符串或回环地址 return QHostAddress(QHostAddress::LocalHost).toString(); } // 获取该接口的所有IP地址列表 QList<QNetworkAddressEntry> entries = interface.addressEntries(); for (const QNetworkAddressEntry &entry : entries) { QHostAddress address = entry.ip(); if (address != QHostAddress::LocalHost && address.protocol() == QAbstractSocket::IPv4Protocol) { return address.toString(); } } return QHostAddress(QHostAddress::LocalHost).toString(); } ``` 这样,我们可以通过传递接口名称(如"eth0"或"wlan0")来获取指定接口的IP地址。 总结:在树莓派上使用QT获取本机IP地址,主要利用`QNetworkInterface`类来获取网络接口信息,然后筛选出需要的IP地址。 §§相关问题§§ 1. 在QT中如何获取所有网络接口的详细信息? 2. 如何区分IPv4和IPv6地址? 3. 树莓派上有多个网络接口时,如何选择正确的接口获取IP地址? 4. QT网络编程中如何处理IP地址的变化(例如DHCP分配的IP地址变化)?</think>### QT框架在树莓派上获取本机IP地址的方法 在QT框架中获取树莓派设备的IP地址,主要通过`QNetworkInterface`类实现。以下是具体方法和代码示例: #### 核心方法 ```cpp #include <QNetworkInterface> #include <QHostAddress> QString getLocalIp() { // 获取所有网络接口的地址列表 QList<QHostAddress> ipList = QNetworkInterface::allAddresses(); for (const QHostAddress &address : ipList) { // 过滤条件:非回环地址 + IPv4地址 if (address != QHostAddress::LocalHost && address.toIPv4Address()) { return address.toString(); // 返回第一个符合条件的IP } } // 默认返回本地回环地址 return QHostAddress(QHostAddress::LocalHost).toString(); } ``` #### 关键说明 1. **`QNetworkInterface::allAddresses()`** 获取设备所有网络接口的IP地址列表,包括IPv4和IPv6地址[^2]。 2. **过滤条件** - `address != QHostAddress::LocalHost`:排除回环地址(127.0.0.1) - `address.toIPv4Address()`:只保留IPv4地址(返回非0值表示有效IPv4) 3. **多网卡场景处理** 若树莓派有多个网络接口(如eth0和wlan0),可通过指定接口名获取: ```cpp QString getInterfaceIp(const QString &interfaceName) { QNetworkInterface interface = QNetworkInterface::interfaceFromName(interfaceName); if (interface.isValid()) { QList<QNetworkAddressEntry> entries = interface.addressEntries(); for (const QNetworkAddressEntry &entry : entries) { if (!entry.ip().isLoopback() && entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { return entry.ip().toString(); } } } return "0.0.0.0"; // 无效时返回 } // 用法:getInterfaceIp("wlan0") 获取无线IP ``` #### 完整使用示例 ```cpp #include <QDebug> int main() { QString ip = getLocalIp(); qDebug() << "树莓派IP地址:" << ip; // 输出示例: "树莓派IP地址: 192.168.42.27" return 0; } ``` #### 注意事项 1. **权限问题** 在Linux系统(包括树莓派)上运行时,确保程序有网络访问权限。 2. **IP变动监听** 如需实时监听IP变化,可结合`QNetworkConfigurationManager`实现网络状态监控。 3. **多IP场景** 当设备有多个IP时(如同时连接有线和无线),上述代码返回第一个有效IP。需要特定IP时应指定接口名[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值