2016-09-27 3 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' шестнадцатеричного значения' é' характера , Итак, вы отправляете строку '' 7E81 '', и приемник преобразует первые два символа (или все из них?) В свои шестнадцатеричные значения. Почему вы имеете дело с шестнадцатеричными значениями вообще? Это очень необычный протокол. –

+0

Поэтому перед отправкой следует преобразовать значение, например. 7E в целое число сначала? Так что, когда он преобразует, он получает правильные данные? – user5313398

+1

Сначала вам нужно объяснить этот протокол связи и что вы пытаетесь выполнить с ним. Использование шестнадцатеричных значений таким способом - это не то, как следует обрабатывать сетевые коммуникации. Что именно этот протокол вы пытаетесь реализовать? –

ответ

2

на основе комментариев в чате:

документация говорят

Start Byte (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 09 40 27 84 94 70 00
Проверить код (1 байт) 19
End байт (1 байт) 7E

поэтому начало и окончание является 7E

для исходящего

Start Byte (1 байт) 7e
ИД сообщения (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 байт) 9А
End байт (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();