Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.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 Netty客户端是否仅与Netty服务器一起工作?_Java_Netty - Fatal编程技术网

Java Netty客户端是否仅与Netty服务器一起工作?

Java Netty客户端是否仅与Netty服务器一起工作?,java,netty,Java,Netty,我正在尝试开发一个客户端,使用自定义协议与生物识别设备进行通信,但似乎没有任何效果。 我使用MessageToByte编码器和MessageToByte解码器来处理输入和输出数据: public class PacketDecoder extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext context, ByteBuf input, List<Object&

我正在尝试开发一个客户端,使用自定义协议与生物识别设备进行通信,但似乎没有任何效果。 我使用MessageToByte编码器和MessageToByte解码器来处理输入和输出数据:

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);
    }
}
公共类PacketDecoder扩展为tetomessagedecoder{
@凌驾
受保护的无效解码(ChannelHandlerContext上下文、ByteBuf输入、列表输出)引发异常{
System.out.println(“可读字节:+input.readableBytes());
if(input.readableBytes()>=1){
if(input.getByte(0)!=datacode.START\u字节){
input.readByte();
返回;
}
}
if(input.readableBytes()>=3){
字节命令=input.getByte(2);
布尔扩展长度=(命令&0x80)==0x80;
短数据长度;
国际人头长度;
if(延长长度){
字节[]dataLengthBytes=新字节[2];
input.getBytes(3,dataLengthBytes);
dataLength=Utils.getShort(dataLengthBytes);
头部长度=5;
}否则{
dataLength=input.getByte(3);
头部长度=4;
}
int totalLength=车头长度+数据长度+16;
if(input.readableBytes()>=总长度){
byte[]packetBytes=input.readBytes(totalength).array();
Packet Packet=PacketConverter.decode(packetBytes);
System.out.println(“数据包解码”);
输出。添加(数据包);
}
}
}
}
公共类PacketEncoder扩展MessageToByteEncoder{
@凌驾
受保护的void encode(ChannelHandlerContext上下文、数据包、ByteBuf out)引发异常{
字节[]packetBytes=PacketConverter.encode(数据包);
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);
        }
    }
}
公共类连接实现PacketListener{
专用最终字节设备地址;
私人渠道未来;
私有EventLoopGroup workerGroup;
私有最终对象readLock=新对象();
专用包响应包;
公共连接(字节设备地址){
this.deviceAddress=设备地址;
}
公共void连接(字符串地址,int端口){
workerGroup=new NioEventLoopGroup();
引导b=新引导();
b、 组(工作组);
b、 通道(NioSocketChannel.class);
b、 选项(ChannelOption.SO_KEEPALIVE,true);
b、 处理程序(新的ChannelInitializer(){
@凌驾
受保护的无效初始化通道(SocketChannel SocketChannel)引发异常{
socketChannel.pipeline().addLast(
新的PacketEncoder(),
新的PacketDecoder(),
新的PacketHandler(Connection.this)
);
}
});
channelFuture=b.connect(地址、端口);
}
公共空间断开连接(){
channelFuture.channel().disconnect().syncunterruptibly();
workerGroup.shutdownGracefully();
}
@凌驾
公共无效接收(数据包){
已同步(读锁){
this.responsePacket=数据包;
readLock.notify();
}
}
公共响应发送(Command,int-responseTimeout)抛出TimeOutException{
数据包=新数据包();
packet.setCommand(command.getCommandCode());
packet.setData(command.getCommandData());
packet.setAddress(设备地址);
已同步(读锁){
responsePacket=null;
channelFuture.channel().writeAndFlush(数据包).syncunterruptibly();
试一试{
readLock.wait(responseTimeout);
}捕捉(中断异常e){
}
if(responsePacket==null)
抛出新的TimeOutException();
返回Response.get(responsePacket);
}
}
}
在解码器上,它总是带有0个可读字节,我不确定编码器是否发送了任何数据。我唯一的猜测是服务器需要是一个Netty实现

Netty客户端是否仅与Netty服务器一起工作

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

虽然您的示例相对简单,但我建议您根据一个工作示例构建代码,然后在这些部分变得更有意义后添加特性/结构。例如,查看。尝试使用此结构,在可以发送/接收一些字节之前,不要担心获得干净的类层次结构(同步、超时等)

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

其他一些常见故障排除问题:

1) 您是否已确认发送的信息正确,并且设备正在接收信息

2) 您是否已验证设备是否响应预期响应

Netty客户端是否仅与Netty服务器一起工作

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

虽然您的示例相对简单,但我建议您根据一个工作示例构建代码,然后在这些部分变得更有意义后添加特性/结构。例如,查看。尝试使用这种结构,在您可以发送之前,不要担心得到一个干净的类层次结构(同步、超时等)/