gpt4 book ai didi

java - Netty 客户端只能与 Netty 服务器一起使用吗?

转载 作者:行者123 更新时间:2023-12-01 17:01:46 26 4
gpt4 key购买 nike

我正在尝试开发一个客户端来使用自定义协议(protocol)与生物识别设备进行通信,但似乎没有任何效果。我使用 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 实现。

最佳答案

Does a Netty client work with a netty server only?

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

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

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

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

1) 您是否已验证您发送的信息是否正确并且设备正在接收该信息?

2) 您是否已确认设备正在按照预期响应进行响应?

关于java - Netty 客户端只能与 Netty 服务器一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27257014/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com