使用netty4组件从tcp端口获取数据的问题

时间:2018-01-14 08:35:27

标签: java tcp apache-camel netty

我正在使用Camel Netty4组件来侦听TCP端口上的数据。以下是我的代码:

public class TcpListener {


    public static void main(String hh[]) throws Exception{

        MyMessageDecoder byteDecoder = new MyMessageDecoder();
        SimpleRegistry reg = new SimpleRegistry();
        reg.put("decoder", byteDecoder);
        CamelContext context = new DefaultCamelContext(reg);

        context.addRoutes(new RouteBuilder() {
            public void configure() {

                from("netty4:tcp://0.0.0.0:5150?decoder=#decoder")
                .to("file://C:/Users/Rahul/Desktop?fileName=tcpOutput.txt");
            }
        });

        context.start();
    }

}

class MyMessageDecoder extends ByteToMessageDecoder {

    static FileWriter writer;
    static {
        try {
            writer = new FileWriter("C:/Users/Rahul/Desktop/tcpOutputNew1.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void decode(ChannelHandlerContext context, ByteBuf buffer, List<Object> out) throws Exception {

        if (buffer.readableBytes() < 1) {
            return;
        }

        byte[] bytes = new byte[1];
        buffer.readBytes(bytes);

        MyMessage myMessage = new MyMessage(bytes);
        System.out.println(bytes[0]);
        System.out.println(Integer.toBinaryString(bytes[0]));
        System.out.println(Integer.toHexString(bytes[0]));
        System.out.println(myMessage);

        out.add(myMessage);
    }
}

class MyMessage {

    protected byte data1;

    public MyMessage(byte[] data) {
        data1 = data[0];
    }

    public String toString() {
        return "MyMessage: { " + this.data1 +" }";
    }
}

在我的代码中,我试图一次读取1个字节,因为在每个字节中我将收到设备的IMEI号。对于IMEI号

351608084153316

我应该收到像

这样的数据
0x03 0x51 0x60 0x80 0x84 0x15 0x33 0x16

但我收到的数据是

0x03 0x51 0x60 0xffffff80 0xffffff84 0x15 0x33 0x16. 

如何解决此问题或如何忽略附加IMEI编号某些部分的这些不需要的字节。

1 个答案:

答案 0 :(得分:1)

以下是发生的事情。

  1. 你有一个字节数组,即使你不关心一个符号位,它也被认为是签名的
  2. 当您尝试使用它们时,它们会自动“升级”为int。由于最左边的位为1,byteint都会被签名,因此会向左传播,因此int值与byte数值相同。从你的例子

    0x03 0x51 0x60 0x80 0x84 0x15 0x33 0x16
    

    第一个字节是0x03或位模式0000_0011。这是一个正值,并被提升为0x000000030x510x60也是如此。 0x80的情况有所不同。其位模式为1000_0000,其数值为-128。提升时,其符号会左延,导致int0xFFFFFF80,其值仍为-128

  3. 实际上,这些都不会影响您,因为低位字节中的位模式没有改变。解决方案就是在从阵列访问字节时屏蔽掉不需要的位。如在

    Integer.toHexString(0x000000FF & (int) bytes[0])