2014-12-02 93 views
0

我想开发一个客户端与使用自定义协议的生物识别设备进行通信,但似乎没有任何工作。 我使用的是MessageToByteEncoder和MessageToByteDecoder来处理输入和输出数据:Netty客户端仅使用Netty服务器吗?

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

和connnection类:

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 readableBytes和我不确定enconder完全发送任何数据。我唯一的猜测是服务器需要成为Netty实现。

回答

4

Netty客户端是否仅使用Netty服务器?

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

虽然你的例子比较简单,但我会建议你将代码从一个工作示例中构建出来,然后在这些部分更有意义时添加特征/结构。例如查看echo examples。尝试使用此结构,并且不必担心在获取一些字节之前获取干净的类层次结构(同步,超时等)。

另外一般情况下,在使用ByteBuf接口时要小心。您的input.getByte(..)调用正在使用不基于readerIndex()的绝对索引编制,这可能导致出界异常。请参阅ByteBuf javadocs,但您可能只想坚持使用readByte()或至少使用readerIndex()

其他一些一般故障排除问题:

1)是否已确认您发送正确的信息和设备正在接收吗?

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

+0

我写了一个测试使用套接字和设备工作正常。我认为netty的实现并没有发送数据,我找不到原因。 – dcidral 2014-12-03 10:48:34

+0

你如何确保频道实际连接? 'channelFuture = b.connect(地址,端口);'操作是异步的。尝试在该调用结束时放置一个'.sync()'。 – 2014-12-03 15:51:53

相关问题