Python + Android APP 方式获取树莓派的 IP

20131115223615279-0

来自 匿名用户1977 的投稿,原文

树莓派实验室之前已经介绍了多种方法,来获得树莓派的 IP 地址。有的利用局域网工具或登录路由器查询、有的通过OLED小屏幕自动显示、还有的使用 Python 将树莓派的 IP 发到邮箱的。

下面我们再来多介绍一种,使用 Python 脚本配合 Android 手机通过 UDP 方式,让手机获取树莓派的 IP 地址。并且允许手机端远程对树莓派进行重启、关机等操作。

本文提供了全部的代码文件,有兴趣的朋友可以测试、完善。

每次要 SSH 到树莓派都很麻烦,我是没找什么办法,每次都得连上显示器鼠标键盘。才能知道IP地址。看了点 Python,写了个脚本来发出 IP 地址,这样就省事多了。

发现启动时有可能早于树莓派网络初始化,会导致 UDP 服务初始化出现问题。脚本里面延时 30 秒执行。在树莓派4测试通过。

创建 Python 脚本

创建的代码文件名 FindIPUDPServer.py,保存在 /home/pi 目录下或者其他你指定的位置。

import socket
import uuid
import time
import os

import time
import logging

from logging import handlers

# 获取MAC地址
def get_mac_address():
    mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
    return ":".join([mac[e:e + 2] for e in range(0, 11, 2)])

# 获取IP地址
def get_host_ip():
    try:
        my = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        my.connect(('8.8.8.8', 80))
        # ip = my.getsockname()[0]
        ipList = my.getsockname()
    finally:
        my.close()
    return ipList

def _logging(**kwargs):
    level = kwargs.pop('level', None)
    filename = kwargs.pop('filename', None)
    datefmt = kwargs.pop('datefmt', None)
    format = kwargs.pop('format', None)
    if level is None:
        level = logging.DEBUG
    if filename is None:
        filename = 'default.log'
    if datefmt is None:
        datefmt = '%Y-%m-%d %H:%M:%S'
    if format is None:
        format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'

    log = logging.getLogger(filename)
    format_str = logging.Formatter(format, datefmt)
    # backupCount 保存日志的数量,过期自动删除
    # when 按什么日期格式切分(这里方便测试使用的秒)
    th = handlers.TimedRotatingFileHandler(filename=filename, when='H', backupCount=3, encoding='utf-8')
    th.setFormatter(format_str)
    th.setLevel(logging.DEBUG)

    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    #  ch.setFormatter(format)
    log.addHandler(ch)

    log.addHandler(th)
    log.setLevel(level)
    return log

os.makedirs("logs", exist_ok=True)
mylog = _logging(filename='logs/udpserver.log')

print("等待30秒")
mylog.debug("等待30秒")
time.sleep(30)
print("等待结束")
mylog.debug("等待结束")

HOST = ''
PORT = 9999
BUFSIZ = 1024
ADDRESS = (HOST, PORT)

udpServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udpServerSocket.bind(ADDRESS)  # 绑定客户端口和地址

myname = socket.gethostname()
print("myname:" + myname)
mylog.debug("myname:" + myname)
myIPList = get_host_ip()
print("myIPList:" + str(myIPList))
mylog.debug("myIPList:" + str(myIPList))
macAddress = get_mac_address()
print("macAddress:" + macAddress)
mylog.debug("macAddress:" + macAddress)

while True:
    print("waiting for message...")
    mylog.debug("waiting for message...")
    data, addr = udpServerSocket.recvfrom(BUFSIZ)
    currCode = data.decode('utf-8')
    print("接收到数据:" +currCode)
    mylog.debug("接收到数据:"+currCode)

    # content = '[%s] %s' % (bytes(ctime(), 'utf-8'), data.decode('utf-8'))
    # 发送服务器时间
    if currCode == "TIME":
        content = "Time:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 发送IP地址
    elif currCode == "IP":
        content = "IP:" + str(myIPList)
        udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 发送mac地址
    elif currCode == "MAC":
        content = "MAC:" + macAddress
        udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 发送ip mac地址
    elif currCode == "IP_MAC":
        content = "IP:" + str(myIPList) + "|MAC:" + macAddress
        udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 退出UDP服务端
    elif currCode == "EXIT":
        content = "服务端退出"
        udpServerSocket.sendto(content.encode('utf-8'), addr)
        # print(content)
        break
    # 重启
    elif currCode == "REBOOT":
        content = "服务端重启"
        udpServerSocket.sendto(content.encode('utf-8'), addr)
        print("服务端开始重启")
        mylog.debug("服务端开始重启")
        os.system('shutdown -r now')
        break
    # 关机
    elif currCode == "SHUTDOWN":
        content = "服务端关机"
        udpServerSocket.sendto(content.encode('utf-8'), addr)
        print("服务端开始关机")
        mylog.debug("服务端开始关机")
        os.system('sudo shutdown -h now')
        break
    else:
        udpServerSocket.sendto("Bad Key".encode('utf-8'), addr)

    # content = '[%s] %s %s' % (bytes(ctime(), 'utf-8'), str(myIPList), macAddress)
    # udpServerSocket.sendto(content.encode('utf-8'), addr)
    print('...received from and returned to:', addr)
    mylog.debug('...received from and returned to:', addr)
udpServerSocket.close()
print("服务端退出")
mylog.debug('服务端退出')

配置树莓派

SSH 登录树莓派运行下面的命令配置开机启动项:

sudo nano /etc/rc/local

如图:

注意修改其中脚本文件的路径为脚本实际存放的路径。

重启树莓派

这个时候怎么看我们的程序是否自启动了呢。登录树莓派 执行  sudo systemctl status rc-local 看看 FindIPUDPServer 是否已经起来了。

Android 客户端和源码

树莓派 Python 脚本配置好以后重启。打开 APP 就能搜到树莓派的IP地址

搜索按钮:点击后等待返回结果。搜索到IP地址后,输入到文本框内。
重启、关机、关闭服务,功能就能用啦。
关闭服务功能可以关闭树莓派的搜索服务。点搜索树莓派就不会发送IP地址了。除非重启树莓派。

APK 文件:https://pan.baidu.com/s/15Un8nEiP5QYnXysJuirweg 提取码: htri
源代码链接:https://pan.baidu.com/s/1WWLc7fd28hTs2LJoZZ68PA 提取码: 14up

这是一篇发布于 4年 前的文章,其中的信息可能已经有所发展或是发生改变,请了解。


2 评论

发表评论

你的邮件地址不会公开


*