我想開發一個客戶端與使用自定義協議的生物識別設備進行通信,但似乎沒有任何工作。 我使用的是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實現。
我寫了一個測試使用套接字和設備工作正常。我認爲netty的實現並沒有發送數據,我找不到原因。 – dcidral 2014-12-03 10:48:34
你如何確保頻道實際連接? 'channelFuture = b.connect(地址,端口);'操作是異步的。嘗試在該調用結束時放置一個'.sync()'。 – 2014-12-03 15:51:53