在 vscode 中使用套接字超时打破循环后数据未保存到磁盘

Data not saved to disk after using socket timeout to break the loop in vscode

Objective

通过pythonsocket从驾驶模拟器获取数据并将其保存到磁盘。

代码和问题

我首先点击开始生成数据的模拟器软件上的'start drive'按钮。然后,我 运行 在 VSCode 中通过单击 'Run Python File' 运行 在 Windows.

中的 powershell 中添加以下代码
import socket
import struct
import pandas as pd
from datetime import datetime

UDP_IP = "127.0.0.1"
UDP_PORT = 9000

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))

appended_data = pd.DataFrame()

while True:
    
    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
    fields = struct.unpack_from('=ddd', data)
    
    
    d = {'y': fields[0],
         'x': fields[1],
         'z': fields[2],
         'Time': datetime.now()}

    df1 = pd.DataFrame([d], columns=d.keys())
    
    appended_data = pd.concat([appended_data, df1])
    
    sock.settimeout(5)

# write DataFrame to an excel sheet 
appended_data.reset_index().to_excel('appended.xlsx')

问题

代码 运行 成功,您可以看到最后两个打印输出如下所示。然后,我在停止生成数据的模拟器软件上单击 'stop drive'。这就是为什么我使套接字超时以中断循环的原因。但是在 sock.settimeout(5) 之后,python 会话结束并且最后一行 appended_data.reset_index().to_excel('appended.xlsx') 没有 运行。我怎样才能把它 运行 作为最后一行,以便将数据保存到 excel sheet?

             y             x         z                       Time
0  6374.120505  40150.996479 -1.735209 2022-04-21 08:06:16.888265
     y             x         z                       Time
0  0.0  40150.996479 -1.735209 2022-04-21 08:06:16.910364
Traceback (most recent call last):
  File "c:\Users\USERNAME\get_data_from_minisim.py", line 21, in <module>
    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
socket.timeout: timed out
PS C:\Users\USERNAME> 

编辑:在查看文档和其他 Whosebug 问题后,我想出了以下未成功的问题

appended_data = pd.DataFrame()

while True:
    try: 
        # time.sleep(5)
        data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
        fields = struct.unpack_from('=ddd', data)
        # print(fields[0],fields[1],fields[2])
        
        d = {'y': fields[0],
            'x': fields[1],
            'z': fields[2],
            'Time': datetime.now()}

        df1 = pd.DataFrame([d], columns=d.keys())
        print(df1)
        appended_data = pd.concat([appended_data, df1])
        # print(appended_data)
    
    except:
        sock.settimeout(5)
        appended_data.reset_index().to_excel('appended.xlsx')  

我也试过:

except sock.settimeout(5) as e:
        if e == "timed out":
            appended_data.reset_index().to_excel('appended.xlsx')

和:

except sock.timeout:
        # write DataFrame to an excel sheet 
        appended_data.reset_index().to_excel('appended.xlsx')

** 但没有任何效果。** 具体来说,在后来的这些尝试中单击 'stop driving' 后循环没有中断。

能否指导我如何打破循环并将 appended_data 保存到 excel?

假设套接字代码正确,这应该会在您的连接超时时保存您的 DataFrame

import socket
import struct
import pandas as pd
from datetime import datetime

UDP_IP = "127.0.0.1"
UDP_PORT = 9000

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # Internet  # UDP
sock.bind((UDP_IP, UDP_PORT))

appended_data = pd.DataFrame()

while True:
    try:
        data, addr = sock.recvfrom(1024)  # buffer size is 1024 bytes
        fields = struct.unpack_from("=ddd", data)

        d = {"y": fields[0], "x": fields[1], "z": fields[2], "Time": datetime.now()}
        # Also you can clean up your code as you can append dict to your DataFrame, so you can omit creation of "df1"
        appended_data = appended_data.append(d, ignore_index=True)

        sock.settimeout(5)
    except socket.timeout as timeout_exception:
        print(f"Lost communication with remote\n{timeout_exception}")
        break

# write DataFrame to an excel sheet
appended_data.reset_index().to_excel("appended.xlsx")

为了让您的代码面向未来的补充说明,documentation 中的示例表明您应该在 with 语句中使用套接字,这是一个很好的做法,因为您不必手动关闭完成后连接。