#夏日挑战赛#【FFH】OpenHarmony与HarmonyOS实现中文交流(二) 原创 精华
龙眼Litchi
发布于 2022-6-19 21:50
浏览
5收藏
在前天发表的OpenHarmony与HarmonyOS的Socket对话文章中存在这样一个问题,那就是传递的中文消息不能被解析!主要原因就是信息的编码问题,本次我们将尝试解决这个问题。
0.效果
- 传递中文出现乱码
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()
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
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.优化后结果
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-6-19 21:50:04修改
赞
13
收藏 5
回复
相关推荐
原来如此 有点东西
好!好!好!
大佬好厉害!
大佬好厉害!