【问题标题】:Retrieving error 'utf-8' codec can't decode byte 0xb2 in position 17: invalid start byte检索错误“utf-8”编解码器无法解码位置 17 中的字节 0xb2:无效起始字节
【发布时间】:2020-12-30 13:48:27
【问题描述】:

客户端

我有以下代码从客户端发送数组到服务器。我正在检索 UTF-8 解码错误。我不喜欢加载数据 pickle 或 zlib compress。我是pyzmq socket来发送数据和接收数据。

def send_array(socket, A, flags=0, copy=True, track=False):
  """send a numpy array with metadata"""
  md = dict(
    dtype = str(A.dtype),
    shape = A.shape,
  )
  socket.send_json(md, flags|zmq.SNDMORE)
  return socket.send(A, flags, copy=copy, track=track)

def forward_data(frame, count):
   source = cv2.imdecode(np.fromstring(base64.b64decode(frame), dtype=np.uint8), 1)
   image = img_to_array(source)
   image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
   preds = m1.predict(preprocess_input(image))
   send_array(dest_socket,preds)

服务器端

def recv_array(socket, flags=0, copy=True, track=False):
"""recv a numpy array"""
  md = socket.recv_json(flags=flags)
  msg = socket.recv(flags=flags, copy=copy, track=track)
  buf = np.buffer(msg)
  A = numpy.frombuffer(buf, dtype=md['dtype'])
  return A.reshape(md['shape'])

def handle_image_processing(frame, count):
  frame_object=recv_array(socket)
  tmp = np.zeros(frame_object.shape)
  for i in range( 0, 1 ):
    tmp[i,:] = tmp[i, :]
    predictions_result = m2.predict( tmp )
    label_vgg16 = decode_predictions( predictions_result )
    print(label_vgg16)

检索错误 Traceback(最近一次调用最后一次):

   handle_image_processing(frame,count)
   File "C:/Pause-Resume-Approach-Updated/server-b.py", line 82, in handle_image_processing
   frame_object=recv_array(socket)
   File "C:/Pause-Resume-Approach-Updated/server-b.py", line 68, in recv_array
   md = socket.recv_json(flags=flags)
   File "C:\Users\learn\miniconda3\envs\tensorflow\lib\site-packages\zmq\sugar\socket.py", line 690, in recv_json
   return self._deserialize(msg, lambda buf: jsonapi.loads(buf, **kwargs))
   File "C:\Users\learn\miniconda3\envs\tensorflow\lib\site-packages\zmq\sugar\socket.py", line 515, in _deserialize
   return load(recvd)
   File "C:\Users\learn\miniconda3\envs\tensorflow\lib\site-packages\zmq\sugar\socket.py", line 690, in <lambda>
   return self._deserialize(msg, lambda buf: jsonapi.loads(buf, **kwargs))
   File "C:\Users\learn\miniconda3\envs\tensorflow\lib\site-packages\zmq\utils\jsonapi.py", line 54, in loads
   s = s.decode('utf8')
   UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 17: invalid start byte

谢谢

【问题讨论】:

  • socket 参数是什么类型的对象?您能否指出哪一行引发了异常和/或包含完整的回溯?
  • 谢谢@lenz,我已经更新了帖子。
  • 看起来您使用socket.send_json 发送的消息不是(或不仅)您使用recv_json 反序列化的消息。混合使用sendsend_json 发送的消息是一种好的模式吗?在服务器端区分这一点可能很棘手(如果有并发请求,对齐两个相应的消息也可能很棘手)。
  • @lenz 这两种方法 { .send(), .send_json() } 实际上都是用来填写一个和唯一一个消息信封(一个多帧的),所以你的假设服务器端必须做一些魔术来猜测哪些到达的消息流是以哪种方式加载的没有实现,但我和你一样怀疑使用上述方法的混合加载多帧消息 { .send (), .send_json(), ... } 原则上如何组成多方开放式分布式计算系统既安全又高效(需要更高效的映射+强大的防御)

标签: python numpy utf-8 zeromq pyzmq


【解决方案1】:

虽然您的代码在发送前使用(正确)zmq.SNDMORE 标志构建多部分消息有效负载,但接收部分忽略任何和所有zmq.RCVMORE 驱动的测试,如果应使用传递消息的任何下一部分.

这样的事情应该可以工作:

while True:
      ...
      if socket.getsockopt( zmq.RCVMORE ):
         continue
      else:
         break

我从未在多帧消息上测试过混合方法 python 代码。原生 ZeroMQ API 在这一点上很清楚,可以使用zmq.RCVMORE-testing 读取直到多帧消息的最后一部分,而python 除了.recv() 之外还移植了一组派生方法,这里使用.recv_json()。如果该端口保留本机 API,则修复后的代码应按预期处理标志,如果不是,则可能会出现一些 pyzmq 副作用的问题,而原始 API 中不存在。

如果对 pyzmq 内置方法 .send_obj() 不满意,可以使用 python struct 模块非常有效地打包字节字段映射的数据元素(.shape.dtype)和 &lt;array&gt;.data()-方法。

代码也应该变得更加健壮,不会收到多部分,而是一个普通的甚至是一个空的消息信封,无论是由于自己的人为错误还是由于对手的入侵。

【讨论】:

    猜你喜欢
    • 2021-01-29
    • 2020-06-09
    • 2021-07-10
    • 2017-07-09
    • 2021-03-05
    • 1970-01-01
    • 2022-11-06
    • 2018-02-10
    相关资源
    最近更新 更多