Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过java套接字发送数据的编码问题?_Java_Sockets - Fatal编程技术网

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

通过java套接字发送数据的编码问题?,java,sockets,Java,Sockets,我有以下代码。我可以很好地读取数据并将数据转换为十六进制。问题是当我发回String replyMessage=“7E81”时,设备将其作为“3745”接收。怎么了?这是由于我的编码,还是我需要在发回之前进行一些转换 w = new BufferedWriter(new OutputStreamWriter(receivedSocketConn1.getOutputStream(),"ISO-8859-15")); // r = new BufferedReader(new InputStre

我有以下代码。我可以很好地读取数据并将数据转换为十六进制。问题是当我发回
String replyMessage=“7E81”时,设备将其作为
“3745”
接收。怎么了?这是由于我的编码,还是我需要在发回之前进行一些转换

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();
    }
}
w=new BufferedWriter(新的OutputStreamWriter(receivedSocketConn1.getOutputStream(),“ISO-8859-15”)//
r=新的BufferedReader(新的InputStreamReader(receivedSocketConn1.getInputStream(),“ISO-8859-15”);
int-nextChar=0;
而((nextChar=r.read())!=-1){
StringBuilder sb=新的StringBuilder();
sb.append(Integer.tohextstring(nextChar));
如果(sb.length()<2){
sb.插入(0,'0');//如果需要,用前导零填充
}
字符串hexChar=sb.toString();
System.out.println(“\n\n十六进制值为”+Integer.tohextstring(nextChar).toUpperCase()+”“+”Int值为“+nextChar”);
message=message+hexChar;
字符串messageID=message.substring(2,6);
System.out.println(“messageId为:“+messageId”);
if(messageID.equals(“0100”)){
字符串replyMessage=“7E81”;
w、 写入(replyMessage+“\r\n”);
w、 冲洗();
}
}

根据聊天室中的评论:

文件上说

开始字节(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 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 30 38 31 33 32 31 39 36
检查代码(1字节)9A
结束字节(1字节)7e

这意味着所讨论的协议是二进制协议,而不是像您所想的那样发送十六进制字符串的文本协议。因此,您使用的
OutputStreamWriter
InputStreamReader
StringBuilder
toHexString()
等对于此协议来说都是完全错误的

接收和发送的每封邮件都以固定的13字节页眉开始,然后是可变长度的正文(页眉指定正文长度),最后是固定的2字节页脚

考虑到这一点,请尝试类似以下内容:

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();
final protected static char[]hexArray=“0123456789ABCDEF.tocharray();
公共静态字符串bytesToHex(字节[]字节){
char[]hexChars=新字符[bytes.length*2];
对于(int j=0;j>>4];
hexChars[j*2+1]=hexArray[v&0x0F];
}
返回新字符串(hexChars);
}
...
w=新的DataOutputStream(新的BufferedOutputStream(receivedSocketConn1.getOutputStream());
r=新的DataInputStream(新的BufferedInputStream(receivedSocketConn1.getInputStream());
...
if(r.readByte()!=0x7E)//开始字节
{
//啊哦,出了点问题!!
receivedSocketConn1.close();
返回;
}
int messageID=r.readUnsignedShort();//消息ID
int bodyLen=r.readUnsignedShort();//消息正文性质(正文长度)
字节[]phoneNum=新字节[6];
r、 readFully(phoneNum);//设备电话号码
int serialNum=r.readUnsignedShort();//消息序列号
byte[]messageBody=新字节[bodyLen];//消息体
r、 readFully(messageBody);
字节检查码=r.readByte();//校验码
if(r.readByte()!=0x7E)//结束字节
{
//啊哦,出了点问题!!
receivedSocketConn1.close();
返回;
}
//TODO:如果需要,验证检查码。。。
System.out.println(“messageId是:0x”+整数.tohextString(messageId));
System.out.println(“phoneNum是:+bytesToHex(phoneNum));
System.out.println(“serialNum是:0x”+Integer.toHexString(serialNum));
System.out.println(“messageBody是:“+bytesToHex(messageBody));
//根据需要处理消息数据。。。
开关(messageID)
{
案例0x100:
{
// ...
字节[]replyBody=新字节[19];
replyBody[0]=0x00;
replyBody[1]=0x01;
回复体[2]=0x00;
replyBody[3]=0x32;
//等等。。。
checkCode=0x9A;//根据需要计算。。。
w、 writeByte(0x7e);//开始字节
w、 writeShort(0x8100);//消息ID
w、 writeShort(replyBody.length);//消息正文性质(正文长度)
w、 写入(phoneNum);//设备电话号码
w、 writeShort(0x0001);//消息序列号
w、 write(replyBody);//消息正文
w、 writeByte(检查代码);//检查代码
w、 writeByte(0x7e);//结束字节
打破
}
//其他需要的消息ID。。。
}
w、 冲洗();

根据聊天室中的评论:

文件上说

开始字节(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 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 30 38 31 33 32 31 39 36
检查代码(1字节)9A
结束字节(1By)