1.如何使用socket将numpy多维数据转发
使用:pickle, pickle是在python中专门用于对数据,变量或者对象进行序列化的包(序列化:我们把变量从内存中变成可存储或传输的过程称之为序列化, 序列化之后相应内容我们可以写入磁盘进行存储)。
使用函数1:pickle.dumps(obj), 表示对obj进行序列化,并返回对应的字节流( 这里的obj 可以是列表,字典,字符串等等各种哦python的数据, 当然也包括numpy数据。),显然只要我们使用pickle.dumps便可以将数据进行字节流的转换,进而使用socket进行数据传输,相应我们在另一端例如服务器端使用的反序列化将收到的字节流再转换为numpy数据就可以了,相应的命令为:pickle.loads()。
例如:
客户端发送程序:one_socket.send(pickle.dumps(data))
服务器端接收:
receive_data = data_socket1.recv(1024)
receive_data = pickle.loads(receive_data )
2.上传服务器显示数据被截断或者破坏。
上述是一种非常简短的收发程序,如果你的数据长度不是很长,并且仅仅只在你的本地端进行传输,那么实际往往不会发生问题,但一旦你上传到服务器,与服务器进行socket连接,则往往会出现标题所示问题,以下列明原因:
(1)我们在数据传输时并没有列明信息的长度判断。
(2)本地计算机和服务器数据处理和读取速度不同,往往服务器更快,这样两者间的读出速度差我们没有考虑。
具体说明:
当本地端发送数据时,计算机是将数据逐个发送的,接收也是如此,而这样我们在服务器端使用recv()进行读取时,很可能会出现服务器读取数据时,本地计算机还没有将数据发送完,或者在服务器接收缓存器中还没有完整的数据,这样的话,我们读取指定数据便会不完整,然后再解析就会报错了。
解决问题:
既然解析时可能会出现数据不完整,那么我们就必须判断数据是否完整,只有完整了我们才会再去解析, 而最好用的判断完整与否的标志就是长度信息。因此我们使用循环来不断接收数据,每次判断数据是否到达指定长度,即可快速解决这一问题,这样的话我们应当在数据发送之前 先发送预发数据的长度信息,告知服务器你要接收的数据长度,如果数据长度不到就要再去读缓存器,直到数据读取完整。
客户端:
# select_data 要发送的数据
one_socket.send(str(len(pickle.dumps(select_data))).encode()) # 先发送数据长度
one_socket.send(pickle.dumps(select_data)) # 再发送数据
服务器端:
while True:
data_len = data_socket1.recv(64) # 先接收数据长度
data_len = int(data_len.decode()) # 解码的数据长度int
data = b"" #建立一个空的字节流,来存储数据
while True:
receive_data = data_socket1.recv(512)# 注意512只是最多读取的字节数而不是实际字节数
data = data + receive_data # 存到字节流
if len(data) == data_len: #判断数据长度是否达到总长度, 到了就说明数据接收完整,要跳
#出循环去解析
break # 数据解析,返回对应的numpy数组
info_data = pickle.loads(data)
当然其中也可以加入读取数据为空的特殊情况台讨论,空的话直接break即可(因为数据不是读完了, 就是可能传传输过程中被破坏了,为防止死在循环中,可以直接break跳出).