本公司是生产智能水表的,有个工程是集中器与后台服务器socket通讯。接到这个任务时,一脸懵逼,因为以前是做安卓的,从来没写过socket通讯,期间,遇到了无数的问题,翻阅了无数资料,经过十几个夜晚的奋斗,终于通讯成功。废话不多说,上硬货~~
当集中器模块链接上服务器时,如果无论怎么发送数据,服务器都接收不到数据或者接收到乱码的时候,请检查集中器模块(GPRS模块或者单片机模块),将心跳包去掉,在这里当时我卡住了两天。
服务器接收到数据后,却解析不出数据,请将读取数据流的方法改成读取字节格式,千万不要读取成string类型,不然后面解析起来会出现乱码。
我们后台的服务器使用java写的,而客户端是由单片机和GPRS组成,单片机发送数据的时候如果发送的是无符号型byte数组,java这里解析起来会出现65533乱码,所以在与客户端人员可以协调一下,将单片机中发送的字节数组格式改变成有符号型byte。
java中byte的取值范围是-128~127,所以,当需要发送大于127(byte型80-FF)的数据的时候,请注意格式转换,代码已经贴在下面
关于字符串转十六进制数组,如下
package com.cb.socket;
public class ZJutils {
static byte[] Str2Bytes(String str) {
byte[] bytes = new byte[str.length() / 2];
String str2 = "";
for (int i = 0; i < str.length() / 2; i++) {
if (i == str.length() - 1) {
str2 = str.substring(2 * i);
} else {
str2 = str.substring(2 * i, 2 * i + 2);
}
byte by=Str2Byte(str2);
bytes[i]=by;
}
return bytes;
}
private static byte Str2Byte(String str) {
char HIGH = str.charAt(0);
char LOW = str.charAt(1);
int high = Char2Int(HIGH);
int low = Char2Int(LOW);
int value = high * 16 + low;
if(value>127){
value-=256;
}
return (byte) value;
}
private static int Char2Int(char low) {
int i = 0;
switch (low) {
case '0':
i = 0;
break;
case '1':
i = 1;
break;
case '2':
i = 2;
break;
case '3':
i = 3;
break;
case '4':
i = 4;
break;
case '5':
i = 5;
break;
case '6':
i = 6;
break;
case '7':
i = 7;
break;
case '8':
i = 8;
break;
case '9':
i = 9;
break;
case 'A':
i = 10;
break;
case 'a':
i = 10;
break;
case 'B':
i = 11;
break;
case 'b':
i = 11;
break;
case 'C':
i = 12;
break;
case 'c':
i = 12;
break;
case 'D':
i = 13;
break;
case 'd':
i = 13;
break;
case 'E':
i = 14;
break;
case 'e':
i = 14;
break;
case 'F':
i = 15;
break;
case 'f':
i = 15;
break;
}
return i;
}
public static void Value(byte[] by2, byte[] by) {
for(int i=0;iby2[i]=by[i];
}
}
}