2

我正在开发一个与本机消息传递主机一起使用的 Chrome 扩展程序。它在大多数情况下都有效,但是当我发送特定大小的消息时,我发现了一种奇怪的行为。当大小在 2560 和 2815 字节之间(十六进制的 A00 和 AFF)时,似乎删除了消息。所有后续消息也未到达,这表明流由于某种原因已损坏。

这是一个精简的 Python 原生消息传递应用程序,可用于对其进行测试:

import sys
import struct

def output(message):
    encoded_message = message.encode('utf-8')

    # Write message size.
    sys.stdout.write(struct.pack('I', len(encoded_message)))
    # Write the message itself.
    sys.stdout.write(encoded_message)
    sys.stdout.flush()

if __name__ == "__main__":
    output('{"type": "%s"}' % ('x'*2820))
    output('{"type": "%s"}' % ('x'*2560))

我收到第一条消息,而不是第二条。

我查看了Chrome 存储库中的代码。似乎负责该功能的功能没有任何特别之处:

void NativeMessageProcessHost::ProcessIncomingData(
    const char* data, int data_size) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

  incoming_data_.append(data, data_size);

  while (true) {
    if (incoming_data_.size() < kMessageHeaderSize)
      return;

    size_t message_size =
        *reinterpret_cast<const uint32*>(incoming_data_.data());

    if (message_size > kMaximumMessageSize) {
      LOG(ERROR) << "Native Messaging host tried sending a message that is "
                 << message_size << " bytes long.";
      Close(kHostInputOuputError);
      return;
    }

    if (incoming_data_.size() < message_size + kMessageHeaderSize)
      return;

    content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
        base::Bind(&Client::PostMessageFromNativeProcess, weak_client_ui_,
            destination_port_,
            incoming_data_.substr(kMessageHeaderSize, message_size)));

    incoming_data_.erase(0, kMessageHeaderSize + message_size);
  }
}

有人知道这里可能发生什么吗?

更新

我在 64 位版本的 Windows 7 和 Windows 8.1 上遇到过这个问题。

我在 Stable、Beta 和 Dev 通道上试用了 Chrome 64 位 - 版本 37、38 和 39。我还尝试了稳定的 Chrome 32 位

我使用 32 位版本的 Python 2.7.7 和 PyInstaller 2.1 为本地消息传递主机创建可执行文件。

4

1 回答 1

2

由于您使用的是 Windows,我怀疑 Windows 正在将回车符 ( \x0D) 添加到换行符 ( \x0A) 中。

根据Python 2.x - 将二进制输出写入标准输出?,在 Windows 上防止修改输出流的一种方法是在将任何内容写入 stdout 之前使用以下代码段。

if sys.platform == "win32":
    import os, msvcrt
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
于 2014-10-03T08:57:49.763 回答