尝试使用 Python 从联网设备上的 TCP 套接字连接获取数据
Trying to get data from a TCP socket connection on a networked device using Python
我正在尝试编写一个简单的 Python 脚本,该脚本连接到多个 Fluke 温湿度计 (DewK 1620A),并将温度和湿度读数写入一个文件,然后我可以将其导入 Splunk。这是我第一次用 Python 尝试任何事情,我真的很接近,但似乎无法确定如何通过 TCP 套接字获取数据。
概览
脚本从外部读取设备列表JSON,然后打开与每个设备的连接,发送命令以获取当前读数,然后将这些读数写入文件。
在我的第一次迭代中,我只是进行了一次“data = s.recv(64)”调用,但设备在返回完整结果时不一致。有时我会得到完整的结果(即“69.64,45.9,0,0”),而其他时候我只会得到部分读数(即“69.64,4”)。
真实循环
在做了一些研究之后,我开始看到有关使用 while True 循环在第二(或第三)遍中获取“其余”数据的建议。我用以下内容更改了简单的 s.recv 调用:
while True:
data = s.recv(64) # Retrieve data from device
if not data: # If no data exists, break loop
continue
f.write(data.decode()) # Write data to logfile
不幸的是,现在脚本将无法完成。我怀疑循环没有退出,但响应不应超过 24 个字节。我不确定如何测试和退出循环。我尝试添加超时,但这会杀死整个脚本。
connectDeviceTCP.py
import datetime
import json
import socket
# the command to be passed to the device
command = "read?\r"
# open the deviceLocation.json file for reading
jsonFile = open("devices.json", "r", encoding="utf-8")
# load the contents of the json file into
locationFile = json.load(jsonFile)
jsonFile.close()
# for each device, connect & retrieve device readings
for device in locationFile["devices"]:
location = device["location"]
host = device["host"]
portStr = device["port"]
# convert the portStr variable from string to integer
port = int(portStr)
# open log file for appending.
f = open("log/" + location + ".log", "a")
try:
# create a socket on client using TCP/IP
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# set socket timeout to 3 seconds
s.settimeout(10)
# connect to host and port
s.connect((host, port))
except TimeoutError:
# write to the log file if the host cannot be reached
f.write(('\n{:%Y-%m-%d %H:%M:%S} - '.format(datetime.datetime.now())) + location + " - Error: " + host + ":" + portStr + " does not respond.")
else:
# send the command to the device
s.sendall(command.encode())
# write the timestamp and location to the log
f.write(('{:%Y-%m-%d %H:%M:%S} - '.format(datetime.datetime.now())) + location + " - ")
while True:
data = s.recv(64) # Retrieve data from device
if not data: # If no data exists, break loop
break
f.write(data.decode()) # Write data to logfile
# --- The following work except the device doesn't always spit out all the data.
# receive message string from device
#data = s.recv(64)
# write returned values to log file.
#f.write(data.decode())
finally:
# disconnect the client
s.close()
# close log file
f.close()
设备与以 \r
终止的线路进行面向线路的通信,因此只需阅读整行 - 将 while True 循环 替换为
data = s.makefile(newline='\r').readline()
f.write(data) # Write data to logfile
我正在尝试编写一个简单的 Python 脚本,该脚本连接到多个 Fluke 温湿度计 (DewK 1620A),并将温度和湿度读数写入一个文件,然后我可以将其导入 Splunk。这是我第一次用 Python 尝试任何事情,我真的很接近,但似乎无法确定如何通过 TCP 套接字获取数据。
概览
脚本从外部读取设备列表JSON,然后打开与每个设备的连接,发送命令以获取当前读数,然后将这些读数写入文件。
在我的第一次迭代中,我只是进行了一次“data = s.recv(64)”调用,但设备在返回完整结果时不一致。有时我会得到完整的结果(即“69.64,45.9,0,0”),而其他时候我只会得到部分读数(即“69.64,4”)。
真实循环
在做了一些研究之后,我开始看到有关使用 while True 循环在第二(或第三)遍中获取“其余”数据的建议。我用以下内容更改了简单的 s.recv 调用:
while True:
data = s.recv(64) # Retrieve data from device
if not data: # If no data exists, break loop
continue
f.write(data.decode()) # Write data to logfile
不幸的是,现在脚本将无法完成。我怀疑循环没有退出,但响应不应超过 24 个字节。我不确定如何测试和退出循环。我尝试添加超时,但这会杀死整个脚本。
connectDeviceTCP.py
import datetime
import json
import socket
# the command to be passed to the device
command = "read?\r"
# open the deviceLocation.json file for reading
jsonFile = open("devices.json", "r", encoding="utf-8")
# load the contents of the json file into
locationFile = json.load(jsonFile)
jsonFile.close()
# for each device, connect & retrieve device readings
for device in locationFile["devices"]:
location = device["location"]
host = device["host"]
portStr = device["port"]
# convert the portStr variable from string to integer
port = int(portStr)
# open log file for appending.
f = open("log/" + location + ".log", "a")
try:
# create a socket on client using TCP/IP
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# set socket timeout to 3 seconds
s.settimeout(10)
# connect to host and port
s.connect((host, port))
except TimeoutError:
# write to the log file if the host cannot be reached
f.write(('\n{:%Y-%m-%d %H:%M:%S} - '.format(datetime.datetime.now())) + location + " - Error: " + host + ":" + portStr + " does not respond.")
else:
# send the command to the device
s.sendall(command.encode())
# write the timestamp and location to the log
f.write(('{:%Y-%m-%d %H:%M:%S} - '.format(datetime.datetime.now())) + location + " - ")
while True:
data = s.recv(64) # Retrieve data from device
if not data: # If no data exists, break loop
break
f.write(data.decode()) # Write data to logfile
# --- The following work except the device doesn't always spit out all the data.
# receive message string from device
#data = s.recv(64)
# write returned values to log file.
#f.write(data.decode())
finally:
# disconnect the client
s.close()
# close log file
f.close()
设备与以 \r
终止的线路进行面向线路的通信,因此只需阅读整行 - 将 while True 循环 替换为
data = s.makefile(newline='\r').readline()
f.write(data) # Write data to logfile