简体   繁体   English

通过Java套接字发送数据的编码问题?

[英]Encoding issue for sending data via java socket?

I have the following code. 我有以下代码。 I can do the reading all well and convert data into hex. 我可以很好地读取并将数据转换为十六进制。 The issue is when I send back String replyMessage = "7E81"; 问题是当我发回String replyMessage = "7E81"; , the device receives it as "3745" . ,设备将其接收为"3745" What is wrong? 怎么了? Is it due to my encoding, or do I need to do some conversion before I send back? 是因为我的编码,还是我需要做一些转换后再发送回去?

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();
    }
}

Based on comments in chat: 基于聊天中的评论:

the documentation say 该文件说

Start Byte (1 Byte) 7e 起始字节(1字节)7e
Message ID (2 Byte) 01 00 讯息编号(2位元组)01 00
Message Body Nature (2 Byte) 00 19 邮件正文性质(2字节)00 19
Phone no. 电话号码。 of Device (6 Byte) 09 40 27 84 94 70 设备字节数(6字节)09 40 27 84 94 70
Message Serial number (2 Byte) 00 01 消息序列号(2字节)00 01
Message Body (N Byte) 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 邮件正文(N字节)00 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
Check Code (1Byte) 19 校验码(1Byte)19
End Byte (1Byte) 7E 结束字节(1Byte)7E

so the start and termination is 7E 所以开始和终止是7E

for outgoing 传出

Start Byte (1 Byte) 7e 起始字节(1字节)7e
Message ID (2 Byte) 81 00 讯息编号(2位元组)81 00
Message Body Nature (2 Byte) 00 13 邮件正文性质(2字节)00 13
Phone no. 电话号码。 of Device (6 Byte) 09 40 27 84 94 70 设备字节数(6字节)09 40 27 84 94 70
Message Serial number (2 Byte) 00 01 消息序列号(2字节)00 01
Message Body (N Byte) 00 01 00 32 30 31 31 31 31 30 38 31 31 33 33 32 31 39 36 邮件正文(N字节)00 01 00 32 30 31 31 31 31 30 38 31 31 33 33 32 31 39 36
Check Code (1Byte) 9A 校验码(1Byte)9A
End Byte (1Byte) 7e 结束字节(1Byte)7e

This means the protocol in question is a binary protocol, not a textual protocol that sends hex strings, like you thought. 这意味着所讨论的协议是二进制协议,而不是您所想的发送十六进制字符串的文本协议。 As such, your use of OutputStreamWriter , InputStreamReader , StringBuilder , toHexString() , etc are all completely wrong for this protocol. 因此,对于该协议,您对OutputStreamWriterInputStreamReaderStringBuildertoHexString()等的使用都是完全错误的。

Each message received and sent begins with a fixed 13-byte header, followed by a variable-length body (the header specifies the body length), and terminated by a fixed 2-byte footer. 每条接收和发送的消息均以固定的13字节标头开头,后跟可变长度的正文(标头指定正文长度),并以固定的2字节页脚结尾。

With that in mind, try something more like this instead: 考虑到这一点,请尝试以下更类似的方法:

final protected static char[] hexArray = "0123456789ABCDEF".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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM