2014-12-02 94 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

相關問題