2016-09-27 84 views
0

我有以下代码。我可以很好地完成读取并将数据转换为十六进制。问题是当我发回String replyMessage = "7E81";时,设备收到它作为"3745"。哪里不对?这是由于我的编码,还是我需要做一些转换之前,我发回?通过java套接字发送数据的编码问题?

w = new BufferedWriter(new OutputStreamWriter(receivedSocketConn1.getOutputStream(),"ISO-8859-15")); // 
r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream(),"ISO-8859-15")); 
int nextChar=0; 
while ((nextChar=r.read()) != -1) {    
    StringBuilder sb = new StringBuilder(); 
    sb.append(Integer.toHexString(nextChar)); 
    if (sb.length() < 2) { 
     sb.insert(0, '0'); // pad with leading zero if needed 
    } 
    String hexChar = sb.toString(); 
    System.out.println("\n\n hex value is "+Integer.toHexString(nextChar).toUpperCase()+" "+"Int value is:"+nextChar);   
    message = message+hexChar; 
    String messageID=message.substring(2,6); 
    System.out.println("messageId is :"+messageID); 
    if(messageID.equals("0100")){ 
     String replyMessage = "7E81"; 
     w.write(replyMessage+"\r\n"); 
     w.flush(); 
    } 
} 
+1

'37'是'7'字符的十六进制值,'45'是'E'字符的十六进制值。所以,你发送的字符串是“7E81”,接收器将前两个字符(或全部)转换为十六进制值。你为什么要处理十六进制值?这是一个非常不寻常的协议。 –

+0

因此,在我发送之前,我应该如何转换7E变成整数先呢?所以,当它转换它得到正确的数据? – user5313398

+1

你需要首先解释这个通信协议,以及你试图用它来完成什么。以这种方式使用十六进制值不是应该如何处理网络通信。你试图实现的协议究竟是什么? –

回答

2

基于在聊天评论:

文档说

起始字节(1个字节)7E
消息ID(2字节)01 00
消息正文自然(2字节)00 19
电话号码的设备(6字节)09 40 27 84 94 70
消息序列号(2字节)00 01
消息正文(N字节)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 40 27 84 94 70 00
校验码(1字节)19
结束字节(1字节)7E

所以一开始和终止是7E

传出

起始字节(1个字节)7E
消息ID(2字节)81 00
留言身体性质(2字节)00 13
电话号码(6字节)09 40 27 84 94 70
消息序列号(2字节)00 01
消息正文(N字节)00 01 00 32 30 31 31 31 31 30 38 31 31 33 33 32 31 39 36
校验码(1字节)9A
结束字节(1字节)7E

这意味着有问题的协议是一个二进制协议,不发送十六进制的字符串,像你以为的文本协议。因此,您对OutputStreamWriter,InputStreamReader,StringBuilder,toHexString()等的使用全都是对此协议完全错误的

接收到的每个消息和发送开始与固定13字节的标题,随后的可变长度体(标题指定体长度),并且通过一个固定的2个字节的注脚终止。

考虑到这一点,尝试一些更喜欢这个:

final protected static char[] hexArray = "ABCDEF".toCharArray(); 
public static String bytesToHex(byte[] bytes) { 
    char[] hexChars = new char[bytes.length * 2]; 
    for (int j = 0; j < bytes.length; j++) { 
     int v = bytes[j] & 0xFF; 
     hexChars[j * 2] = hexArray[v >>> 4]; 
     hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
    } 
    return new String(hexChars); 
} 

... 

w = new DataOutputStream(new BufferedOutputStream(receivedSocketConn1.getOutputStream())); 
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream())); 

... 

if (r.readByte() != 0x7E) // start byte 
{ 
    // ah oh, something went wrong!! 
    receivedSocketConn1.close(); 
    return; 
} 

int messageID = r.readUnsignedShort();  // message ID 
int bodyLen = r.readUnsignedShort();  // message body nature (body length) 
byte[] phoneNum = new byte[6]; 
r.readFully(phoneNum);      // device phone number 
int serialNum = r.readUnsignedShort();  // message serial number 
byte[] messageBody = new byte[bodyLen]; // message body 
r.readFully(messageBody); 
byte checkCode = r.readByte();    // check code 

if (r.readByte() != 0x7E) // end byte 
{ 
    // ah oh, something went wrong!! 
    receivedSocketConn1.close(); 
    return; 
} 

// TODO: validate checkCode if needed... 

System.out.println("messageId is : 0x" + Integer.toHexString(messageID)); 
System.out.println("phoneNum is : " + bytesToHex(phoneNum)); 
System.out.println("serialNum is : 0x" + Integer.toHexString(serialNum)); 
System.out.println("messageBody is : " + bytesToHex(messageBody)); 

// process message data as needed... 

switch (messageID) 
{ 
    case 0x100: 
    { 
     // ... 

     byte[] replyBody = new byte[19]; 
     replyBody[0] = 0x00; 
     replyBody[1] = 0x01; 
     replyBody[2] = 0x00; 
     replyBody[3] = 0x32; 
     // and so on... 

     checkCode = 0x9A; // calculate as needed... 

     w.writeByte(0x7e);    // start byte 
     w.writeShort(0x8100);   // message ID 
     w.writeShort(replyBody.length); // message body nature (body length) 
     w.write(phoneNum);    // device phone number 
     w.writeShort(0x0001);   // message serial number 
     w.write(replyBody);    // message body 
     w.writeByte(checkCode);   // check code 
     w.writeByte(0x7e);    // end byte 

     break; 
    } 

    // other message IDs as needed... 
} 

w.flush();