2016-09-27 123 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();