Netty客户端只能与Netty服务器一起使用吗? [英] Does a Netty client work with a netty server only?

查看:266
本文介绍了Netty客户端只能与Netty服务器一起使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个客户端,以使用自定义协议与生物识别设备进行通信,但似乎无济于事. 我正在使用MessageToByteEncoder和MessageToByteDecoder处理输入和输出数据:

I'm trying to develop a client to communicate with a biometric device using a custom protocol but nothing seems to work. I'm using a MessageToByteEncoder and a MessageToByteDecoder to handle the input and output data:

public class PacketDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext context, ByteBuf input, List<Object> out) throws Exception {
        System.out.println("readable bytes: " + input.readableBytes());
        if (input.readableBytes() >= 1) {
            if (input.getByte(0) != DataCodes.START_BYTE) {
                input.readByte();
                return;
            }
        }
        if (input.readableBytes() >= 3) {
            byte command = input.getByte(2);
            boolean extendedLenght = (command & 0x80) == 0x80;
            short dataLength;
            int headerLength;
            if (extendedLenght) {
                byte[] dataLengthBytes = new byte[2];
                input.getBytes(3, dataLengthBytes);
                dataLength = Utils.getShort(dataLengthBytes);
                headerLength = 5;
            } else {
                dataLength = input.getByte(3);
                headerLength = 4;
            }

            int totalLength = headerLength + dataLength + 16;
            if (input.readableBytes() >= totalLength) {
               byte[] packetBytes = input.readBytes(totalLength).array();
                Packet packet = PacketConverter.decode(packetBytes);
                System.out.println("packet decoded");
                out.add(packet);
            }
        }
    }
}


public class PacketEncoder extends MessageToByteEncoder<Packet> {
    @Override
    protected void encode(ChannelHandlerContext context, Packet packet, ByteBuf out) throws Exception {
        byte[] packetBytes = PacketConverter.encode(packet);
        out.writeBytes(packetBytes);
    }
}

和连接类:

public class Connection implements PacketListener {
    private final byte deviceAddress;
    private ChannelFuture channelFuture;
    private EventLoopGroup workerGroup;
    private final Object readLock = new Object();
    private Packet responsePacket;

    public Connection(byte deviceAddress) {
        this.deviceAddress = deviceAddress;
    }

    public void connect(String address, int port) {
        workerGroup = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(workerGroup);
        b.channel(NioSocketChannel.class);
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast(
                        new PacketEncoder(),
                        new PacketDecoder(),
                        new PacketHandler(Connection.this)
                );
            }
        });

        channelFuture = b.connect(address, port);
    }

    public void disconnect() {
        channelFuture.channel().disconnect().syncUninterruptibly();
        workerGroup.shutdownGracefully();
    }

    @Override
    public void receive(Packet packet) {
        synchronized (readLock) {
            this.responsePacket = packet;
            readLock.notify();
        }
    }

    public Response send(Command command, int responseTimeout) throws TimeOutException {
        Packet packet = new Packet();
        packet.setCommand(command.getCommandCode());
        packet.setData(command.getCommandData());
        packet.setAddress(deviceAddress);

        synchronized (readLock) {
            responsePacket = null;
            channelFuture.channel().writeAndFlush(packet).syncUninterruptibly();
            try {
                readLock.wait(responseTimeout);
            } catch (InterruptedException e) {
            }
            if (responsePacket == null)
                throw new TimeOutException();
            return Response.get(responsePacket);
        }
    }
}

在解码器上,它附带了0个可读字节,我不确定该编码器是否正在发送任何数据.我唯一的猜测是服务器需要是Netty实现.

On the decoder, it aways comes with 0 readableBytes and I not sure the enconder is sending any data at all. My only guess is that the server needs to be a Netty implementation.

推荐答案

Netty客户端只能与Netty服务器一起使用吗?

Does a Netty client work with a netty server only?

不.总的来说,Netty提供了网络抽象和事件循环构造,以减轻滚动自己的痛苦和陷阱.

No. In general Netty provides networking abstractions and event-loop constructs to alleviate the pains and pitfalls of rolling your own.

尽管您的示例相对简单,但我还是建议您从一个有效的示例中构建代码,然后在各部分变得更有意义时再添加功能部件/结构.例如,查看回声示例.尝试使用此结构,在可以发送/接收一些字节之前,不要担心会获得干净的类层次结构(同步,超时等).

Although your example is relatively simple I would recommend structuring your code off of a working example and then add features/structure once the pieces make more sense. For example check out the echo examples. Try using this structure and don't worry about getting a clean class hierarchy (synchronization, timeouts, etc..) until you can send/receive some bytes.

通常,在使用ByteBuf界面时也要小心.您的input.getByte(..)调用使用的绝对索引不是基于readerIndex()的,这可能会导致超出范围的异常.请参考 ByteBuf Javadocs ,但您可能只想坚持readByte()或至少使用readerIndex().

Also in general be careful when you are using the ByteBuf interface. Your input.getByte(..) calls are using absolute indexing which is not based on the readerIndex() which may lead to out of bounds exceptions. Please refer to the ByteBuf javadocs but you may just want to stick with readByte() or at least use readerIndex().

其他一些常见的疑难解答问题:

Some other general troubleshooting questions:

1)您是否已验证发送了正确的信息并且设备正在接收信息?

1) Have you verified that you are sending correct information and the device is receiving it?

2)您是否已验证设备正在以预期的响应进行响应?

2) Have you verified the device is responding with the anticipated response?

这篇关于Netty客户端只能与Netty服务器一起使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆