ilovejay88 发表于 2024-4-28 20:49

py写的PING通IP向其发送指令,有点小问题,求助

本帖最后由 ilovejay88 于 2024-4-28 21:30 编辑

各位大神好,帮小弟看下这段代码,我这段代码是想当某个IP通时,向其UDP发送一个指令,然后为了后期增加IP或者修改IP方便,我把IP文本做在INI文件中用来读取,但是似乎在读取过程中出现问题,能帮我分析下吗,感激不尽

import os
import time
import datetime
import socket
import configparser
from subprocess import Popen, PIPE, call

# 存储已ping通的IP地址
pinged_ips = []

# 读取配置文件的路径
CONFIG_FILE = "config.ini"

# 如果配置文件不存在,则创建一个空的配置文件
if not os.path.exists(CONFIG_FILE):
    with open(CONFIG_FILE, 'w') as f:
      f.write("\n")# 写入节
      f.write("10.111.96.202:23 = \\x04\n")# 写入键值对
      f.write("10.111.96.203:23 = \\x05\n")# 写入键值对
      f.write("10.111.96.204:23 = \\x06\n")# 写入键值对
      f.write("\n")# 空行
      f.write("\n")# 写入节
      f.write("time = 23:00\n")# 写入键值对

# 创建ConfigParser对象
config = configparser.ConfigParser()

# 读取INI文件
config.read(CONFIG_FILE)

# 获取IP地址和指令
ip_commands = dict(config.items('ip_commands'))
shutdown_time = config.get('shutdown', 'time')

# 延迟10秒
time.sleep(10)

# 获取当前时间
def get_current_time():
    return datetime.datetime.now().strftime('%H:%M')

# 发送UDP数据包
def send_udp_command(ip, port, command):
    try:
      with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
            server_address = (ip, int(port))
            sock.sendto(command.encode(), server_address)
            print(f"对 {ip}:{port} 已发送开机指令")
    except Exception as e:
      print(f"发送数据到 {ip}:{port} 时出错: {str(e)}")

# 主循环
while True:
    current_time = get_current_time()
    if current_time >= shutdown_time:
      print("到达预设关闭时间,程序即将退出。")
      os._exit(0)# 安全退出程序

    for key, command in ip_commands.items():
      ip, port = key.split(':')
      if ip not in pinged_ips:
            # 尝试ping IP地址
            try:
                response = call(['ping', '-n', '1', ip], stdout=PIPE, stderr=PIPE)
                if response == 0:# ping成功
                  pinged_ips.append(ip)
                  send_udp_command(ip, port, command)
                  # 根据IP打印特定的启动信息
                  if ip == "10.111.92.202":
                        print("6号厅还音柜启动")
                  elif ip == "10.111.96.114":
                        print("2号厅启动")
                  elif ip == "10.111.96.115":
                        print("3号厅启动")
                  time.sleep(2)# 等待2秒
            except Exception as e:
                print(f"尝试ping {ip} 时出错: {str(e)}")

    time.sleep(60)# 主循环等待60秒




下面是INI中的文本。

10.111.96.202:23 = \x04
10.111.96.203:23 = \x05
10.111.96.204:23 = \x06


time = 23:00


Python运行调试报错
ValueError: not enough values to unpack (expected 2, got 1)

devilpanama 发表于 2024-4-28 21:09

{'10.111.96.202': '23 = \\x04', '10.111.96.203': '23 = \\x05', '10.111.96.204': '23 = \\x06'}
字典值不对吧

ilovejay88 发表于 2024-4-28 21:13

devilpanama 发表于 2024-4-28 21:09
{'10.111.96.202': '23 = \\x04', '10.111.96.203': '23 = \\x05', '10.111.96.2 ...

请大神明示。。。

thepoy 发表于 2024-4-28 21:27

本帖最后由 thepoy 于 2024-4-28 21:29 编辑

最重要的不是代码,而是报错信息。

啥年代还用 ini 啊,换 toml 吧。

没用过 ini 解析器,看着像是解析器的问题,但你这么点配置不如自己写一个简单的解析器。

或者如果你用的是 windows 的话,你可以试试把"\n"换成"\r\n"试试。

ilovejay88 发表于 2024-4-28 21:31

thepoy 发表于 2024-4-28 21:27
最重要的不是代码,而是报错信息。

啥年代还用 ini 啊,换 toml 吧。


ValueError: not enough values to unpack (expected 2, got 1)

报错就是报的这个
换行符的问题?

FitContent 发表于 2024-4-28 21:33

默认情况下,`.ini` 文件把符号 `:` 也视为 `key、value` 的分割符,也就是说:下面的两种语法都是可以的。

```python
key1 = value1
key1 : value1
```



而写入的 `ip` 地址中包含了符号 `:`,所以 `xxx:yy = zz` 被解释为 `xxx 和 yy = z` 这两个部分了。



具体可以见官方的文档(https://docs.python.org/3/library/configparser.html#supported-ini-file-structure),在 `Supported INI File Structure` 小节中说明。



解决方法就是:**指明使用 `=` 作为分割符**,修改如下代码即可

```python
config = configparser.ConfigParser(delimiters=('='))
```

ilovejay88 发表于 2024-4-28 21:49

FitContent 发表于 2024-4-28 21:33
默认情况下,`.ini` 文件把符号 `:` 也视为 `key、value` 的分割符,也就是说:下面的两种语法都是可以 ...

感谢老大,解决了我的问题。谢谢

devilpanama 发表于 2024-4-28 21:49

你要的字典应该是key='10.111.96.202: 23'value='\\x04',但是读取时变成key='10.111.96.202' value= '23 = \\x04'
页: [1]
查看完整版本: py写的PING通IP向其发送指令,有点小问题,求助