当前位置: 首页 > 面试题库 >

具有chrome扩展名的Java本机消息传递-无法正确写入长度

吕华彩
2023-03-14
问题内容

我目前正在编写一个与Chrome扩展程序通信的Java程序。我需要实现Chrome本机消息传递协议才能进行通信。Google Chrome文档说:

…每条消息都使用JSON(UTF-8编码)进行序列化,并以本机字节顺序开头32位消息长度。(来源)

我尝试用Java实现此功能,但是即使我的实现应该是正确的,但是当我的消息具有一定长度时,我还是会遇到问题。这是我当前的实现,基于早期的SO-answers和问题:

// read the message size from Chrome. This part works correctly.
public static int getInt(char[] bytes) {
    return  (bytes[3]<<24) & 0xff000000|
            (bytes[2]<<16) & 0x00ff0000|
            (bytes[1]<< 8) & 0x0000ff00|
            (bytes[0]<< 0) & 0x000000ff;
}

// transform the length into the 32-bit message length. 
// This part works for small numbers, but does not work for length 2269 for example.
public static String getBytes(int length) {
    return String.format("%c%c%c%c", 
            (char) ( length      & 0xFF),
            (char) ((length>>8)  & 0xFF),
            (char) ((length>>16) & 0xFF),
            (char) ((length>>24) & 0xFF));
}

看来问题出在java实现chars的方式上。我期望普通的字符,例如C语言。在实践中,似乎Java有时会将这些字符转换为unicode-
chars(或者至少到目前为止,我一直对此表示怀疑)。这反映在java程序的长度为2269的以下输出中(通过管道传输到xxd以显示实际的字节):

0000000: c39d 0800 00                             .....

但是,预期输出(使用python):

import struct
struct.pack('I', 2269)
# outputs in interactive mode: '\xdd\x08\x00\x00'

这里到底发生了什么?Java为什么将我的“ 0xDD”转换为“ 0xC39D”,我如何获得getBytes代表Chrome Native Messaging预期输入的函数?不能使用其他语言。


问题答案:

Java中的字符会自动转换为unicode。此用例的正确类型是byte,它不会自动转换并保留正确的值。因此,Chrome Native
Messaging协议的正确实现如下:

    public static byte[] getBytes(int length) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) ( length      & 0xFF);
        bytes[1] = (byte) ((length>>8)  & 0xFF);
        bytes[2] = (byte) ((length>>16) & 0xFF);
        bytes[3] = (byte) ((length>>24) & 0xFF);
        return bytes;
    }

除此方法外,还需要注意不要在长度字节的计算和输出之间的任何地方使用String。输出到System.out可以执行以下操作:

    try {
        System.out.write(getBytes(message.length()));
    } catch (IOException ex) {
        ex.printStackTrace();
    }


 类似资料:
  • 问题内容: 我正在尝试在内容脚本和扩展名之间传递消息 这是我的内容脚本 在后台脚本中 现在,如果我在函数中的ajax调用之前发送响应,则响应已成功发送,但是在ajax调用的成功方法中,当我发送响应时它不会发送响应,而在进行调试时,我可以看到该函数代码中的端口为null 。 问题答案: 从文档中: 当事件侦听器返回时,此函数将变为无效,除非您从事件侦听器返回true表示您希望异步发送响应(这将使消息

  • 我正在玩MP Reactive Messaging和MP Opentracing,但我不知道如何跟踪通过Reactive Messaging发送的消息。 甚至有可能跟踪带有@income/@output注释的方法吗?

  • 这是我的控制器 null 以及访问时使用,但有没有其他解决方案不会更改和URL中的值?

  • 我正在尝试在我的应用程序中实现Firebase云消息传递,我已经实现了使用此服务的所有设置,但是当我尝试在我的类中扩展时,它给了我错误,它根本找不到它,我甚至不能如图所示: 我已经添加了所需的所有代码:我将此添加到app gradle 这是模块等级: 这是清单代码: 我把谷歌json文件添加到应用程序中。所以如果有人能帮助我

  • 我是Spring MVC框架的新手。我试图在我的Spring项目中使用Hibernate返回object来检索用户详细信息。我得到以下错误: 警告:org.springframework.web.servlet.mvc.support.defaultHandlerExceptionResolver-无法写入HTTP消息:org.springframework.HTTP.converter.http

  • 这是我的代码Rest我的api上传文件 我的API有一个验证,当这个请求made.For上面的请求时,它会检查文件扩展名. xml我的api没有收到. xml文件扩展名,所以它会给出400个错误 仅供参考:使用Postman时,同样的请求也能正常工作