Socket传输Hickle(HDF5)文件后出现OSError:无法打开文件
问题:Socket传输hickle文件后服务器加载失败(OSError: 文件签名未找到)
我近期编写了一套基于Socket的客户端/服务器程序,用于传输hickle(基于HDF5的文件)格式文件。本地生成、导入及读取该文件均正常,但通过Socket传输后,服务器端执行data = hickle.load("temp.hkl")加载接收的文件时,出现OSError: Unable to open file (file signature not found)错误。
客户端发送代码
import socket import hickle # Creating a socket with IPv4 and TCP node_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Define Target node_socket.connect(("127.0.0.1", 1961)) # Send process with open("my_file.hkl", "rb") as f: while True: bytes_read = f.read(4096) if not bytes_read: break node_socket.sendall(bytes_read)
服务器接收代码
import socket import hickle # Creating a socket with IPv4 and TCP node_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind port and set it to listen state node_socket.bind(("127.0.0.1", 1961)) node_socket.listen(1) # Accept incoming connection client_socket, addr = node_socket.accept() # Receive and write to file operation with open("temp.hkl", "wb") as f: while True: recieved_pyload = client_socket.recv(4096) if not recieved_pyload: break f.write(recieved_pyload)
完整报错栈信息
Traceback (most recent call last): File "C:\Users\...\network_connector_server.py", line 3, in <module> data = hickle.load("temp.hkl") File "C:\Users\...\lib\site-packages\hickle\hickle.py", line 321, in load h5f, path, close_flag = file_opener(file_obj, path, 'r', filename) File "C:\Users\...\lib\site-packages\hickle\fileio.py", line 147, in file_opener return h5.File(f, mode.replace('b','')),path,True File "C:\Users\...\lib\site-packages\h5py\_hl\files.py", line 567, in __init__ fid = make_fid(name, mode, userblock_size, fapl, fcpl, swmr=swmr) File "C:\Users\...\lib\site-packages\h5py\_hl\files.py", line 231, in make_fid fid = h5f.open(name, flags, fapl=fapl) File "h5py\_objects.pyx", line 54, in h5py._objects.with_phil.wrapper File "h5py\_objects.pyx", line 55, in h5py._objects.with_phil.wrapper File "h5py\h5f.pyx", line 106, in h5py.h5f.open OSError: Unable to open file (file signature not found) Process finished with exit code 1
请问是否需要先将文件转换为HDF5文件或进行其他处理?
解决方案
核心问题是客户端代码的缩进错误:sendall被写在了while循环外面,循环结束后bytes_read是空值,等于只给服务器发了空数据,导致接收的temp.hkl是个空文件,没有HDF5的文件签名,触发报错。不需要把hickle转成HDF5,直接传输二进制文件即可,修正代码如下:
修正后的客户端代码
import socket # Creating a socket with IPv4 and TCP node_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Define Target node_socket.connect(("127.0.0.1", 1961)) # Send process - 将sendall移入循环内部,每次读取后立即发送 with open("my_file.hkl", "rb") as f: while True: bytes_read = f.read(4096) if not bytes_read: break node_socket.sendall(bytes_read) node_socket.close() # 发送完毕关闭连接,让服务器感知传输结束
服务器代码微调(修正拼写+补充关闭逻辑)
import socket import hickle # Creating a socket with IPv4 and TCP node_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind port and set it to listen state node_socket.bind(("127.0.0.1", 1961)) node_socket.listen(1) # Accept incoming connection client_socket, addr = node_socket.accept() # Receive and write to file operation with open("temp.hkl", "wb") as f: while True: received_payload = client_socket.recv(4096) # 修正拼写错误:recieved_pyload -> received_payload if not received_payload: break f.write(received_payload) client_socket.close() # 关闭客户端连接 node_socket.close() # 关闭服务器监听套接字 # 现在加载文件可正常执行 data = hickle.load("temp.hkl")
内容的提问来源于stack exchange,提问作者Aiden3301
相关产品推荐
相关产品推荐

