[本文正在参加星光计划3.0-夏日挑战赛]

在前天发表的OpenHarmony与HarmonyOS的Socket对话文章中存在这样一个问题,那就是传递的中文消息不能被解析!主要原因就是信息的编码问题,本次我们将尝试解决这个问题。

0.效果

  • 传递中文出现乱码
    14181283b38ce5d066c471d6812666f820226192138523.gif
    7c0a3376ac23084df3ad4083bc79528820226192140564.gif

    1.分析原因

    可以看到在前一篇博文,我们在Harmony端用JAVA编写的Socket发送的数据流是UTF8格式编码的,但是在OpenHarmony端的JS侧把该信息流当做UNICODE编码来解析,中文在这个过程中无法被正确解析。那我们干脆在JAVA侧提前把中文转换成unicode编码再传输过去,JS侧同样用unicode解码即可。
    HarmonyOS和OpenHarmony基本通信搭建可以参考我的前一篇博文哦
    OpenHarmony与HarmonyOS信息交流(一)

    2.HarmonyOS-JAVA侧

    每次发送信息前,都将信息通过unicode函数转换成unicode编码的字符串形式。

  • unicode()
    
    public static String unicode(String str) {
    //存放结果
    StringBuffer res = new StringBuffer();
    //将发送的信息转换成字符数组
    char[] tmp = str.toCharArray();
    //将字符转换成unicode编码
    String unicode = null;
    for (int i = 0; i < tmp.length; i++) {
    //10-16进制的转换
    unicode = Integer.toHexString(tmp[i]);
    //长度小于2的时候,00补齐
    if (unicode.length() <= 2) {
    unicode = "00" + unicode;
    }
    //转换成 /u形式的unicode编码
    res.append("\\u" + unicode);
    }
    //返回unicode编码的字符串形式
    return res.toString();
    }
+ sendMessage()
```java
    private void sendMessage() {
        Mythread.inBG(new Runnable() {
            @Override
            public void run() {
                NetManager netManager = NetManager.getInstance(null);

                if (!netManager.hasDefaultNet()) {
                    HiLog.error(LABEL_LOG,
                            "netManager.hasDefaultNet() failed");

                    return;
                }

                NetHandle netHandle = netManager.getDefaultNet();

                // 通过Socket绑定来进行数据传输
                DatagramSocket socket = null;

                try {
                    //从textfield组件获取用户输入的对端ip地址
                    HOST = iptf.getText();

                    InetAddress address = netHandle.getByName(HOST);
                    socket = new DatagramSocket();
                    netHandle.bindSocket(socket);

                    /*至此 已绑定对端Socket*/

                    //从一个textfield组件获取用户输入的要发送的信息。
                    String data = new String(sendtf.getText());

                    /************增加新的编码方式***************/
                    data=unicode(data);
                    /************增加新的编码方式***************/

                    //这里默认还是发送至对端的10006端口
                    DatagramPacket request = new DatagramPacket(data.getBytes(
                            "UTF-8"), data.length(),
                            address, PORT);
                    // buffer赋值
                    // 发送数据

                    socket.send(request);
                    HiLog.info(LABEL_LOG, "send data: " + data);
                } catch (IOException e) {
                    HiLog.error(LABEL_LOG, "send IOException: ");
                } finally {
                    if (null != socket) {
                    }
                }
            }
        });
    }

3.OpenHarmony-JS侧

前面HarmonyOS传来的是unicode编码的字符串形式,进行了10进制-16进制的转换,那么我们这里进行16进制-10进制转换,进行unicode解码即可。

  • unicodeTostr()
    
    unicodeTostr(str){
var res = []; //存放结果
var tmp = str.split('\\u');//根据 \u 分割
var len = tmp.length; //长度
    for(var i=0; i<len; i++){
     if(tmp[i]){
                        //unicode解码
res.push(String.fromCharCode(parseInt(tmp[i], 16)));//16 转 10
                    }
                }
     return res.join('');
            },
+ creatSocket
```javascript
    creatSocket: async function(){
        var that = this;
        this.udp.bind({address: this.localip, port: 10006, family: 1}, err => {
            if (err) {
                console.info('bind fail');
                this.title='bind fail'
                return;
            }
            this.title='bind success';
            console.info('bind success');
        })
       this.udp.on('message', value => {
           let buffer = value.message;
           let dataView = new DataView(buffer);
           let str = "";
           for (let i = 0;i < dataView.byteLength; ++i) {
               str += String.fromCharCode(dataView.getUint8(i))
           }
           //多加一步就好了  unicode解码
           that.title = that.unicodeTostr(str);

        });
    },

4.优化后结果

6.gif

7.gif

想了解更多关于开源的内容,请访问:

51CTO 开源基础软件社区

https://ost.51cto.com/#bkwz