【发布时间】:2014-12-03 10:02:31
【问题描述】:
我正在尝试开发一个客户端以使用自定义协议与生物识别设备进行通信,但似乎没有任何效果。 我正在使用 MessageToByteEncoder 和 MessageToByteDecoder 来处理输入和输出数据:
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 实现。
【问题讨论】: