Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用Netty框架问题_Java_Netty - Fatal编程技术网

Java 用Netty框架问题

Java 用Netty框架问题,java,netty,Java,Netty,框架似乎不起作用。。。当两个客户端同时连接时,我从这两个客户端获得的数据应该是不同的 当客户端的通道变为活动状态时,它会发送一个握手请求,该请求几乎只是一个带有服务器主机名的字符串,以允许服务器从数据库中获取有关它的一些详细信息 @Override public void channelActive(ChannelHandlerContext context) { HandshakeRequest packet = new HandshakeRequest(); packet.s

框架似乎不起作用。。。当两个客户端同时连接时,我从这两个客户端获得的数据应该是不同的

当客户端的通道变为活动状态时,它会发送一个握手请求,该请求几乎只是一个带有服务器主机名的字符串,以允许服务器从数据库中获取有关它的一些详细信息

@Override
public void channelActive(ChannelHandlerContext context) {
    HandshakeRequest packet = new HandshakeRequest();
    packet.setHostname(Client.HOSTNAME);
    context.writeAndFlush(packet);
}
握手请求:

@Getter @Setter private String hostname;

public HandshakeRequest() {
    super(Packet.HANDSHAKE_REQUEST);
}

@Override
public void write(ByteBuf buf) {
    writeString(hostname, buf);
}

@Override
public void read(ByteBuf buf) {
    hostname = readString(buf);
}
初始值设定项:

@Override
public void initChannel(SocketChannel channel) {
    ChannelPipeline pipeline = channel.pipeline();

    pipeline.addLast(new LengthFieldPrepender(2));
    pipeline.addLast(new PacketEncoder());

    pipeline.addLast(new LengthFieldBasedFrameDecoder(Short.MAX_VALUE, 0, 2, 0, 2));
    pipeline.addLast(new PacketDecoder());

    pipeline.addLast(new ClientHandler(client));
}
包装编码器:

@Override
protected void encode(ChannelHandlerContext context, DefinedPacket packet, ByteBuf buf) {
    buf.writeInt(packet.packet().getId());
    packet.write(buf);
}
打包解码器:

@Override
protected void decode(ChannelHandlerContext context, ByteBuf in, List<Object> out) {
    int id = in.readInt();
    DefinedPacket packet = Packet.getTypeById(id).getPacket();
    if(packet != null) {
        packet.read(in);
        packet.setId(id);
        out.add(packet);
    } else {
        in.skipBytes(in.readableBytes());
    }
}
@覆盖
受保护的无效解码(ChannelHandlerContext上下文、ByteBuf输入、列表输出){
int id=in.readInt();
DefinedPacket=packet.getTypeById(id).getPacket();
if(数据包!=null){
数据包读取(in);
packet.setId(id);
输出。添加(数据包);
}否则{
in.skipBytes(in.readableBytes());
}
}
DefinedPacket(这是一个由所有数据包扩展的抽象类):

公共静态void writeString(字符串s,ByteBuf buf){
如果(s.length()>Short.MAX_值){
抛出新的OverflowPacketException(String.format(“无法发送长度超过Short.MAX_值(获取%s个字符)”,s.length());
}
byte[]b=s.getBytes(Charsets.UTF_8);
WritePrint(b.长度,buf);
buf.写入字节(b);
}
公共静态字符串读取字符串(ByteBuf buf){
int len=读数变量(buf);
如果(长度>短最大值){
抛出新的OverflowPacketException(String.format(“无法接收长度超过Short.MAX_值(已获取%s个字符)”,len));
}
字节[]b=新字节[len];
buf.readBytes(b);
返回新字符串(b,Charsets.UTF_8);
}
公共静态int readVarInt(ByteBuf输入){
返回readVarInt(输入,5);
}
公共静态整型readVarInt(字节输入,整型最大字节){
int out=0;
int字节=0;
字节输入;
while(true){
in=input.readByte();
out |=(in&0x7F)最大字节数){
抛出新的RuntimeException(“变量太大”);
}
如果((in&0x80)!=0x80){
打破
}
}
返回;
}
公共静态void writePrint(int值,ByteBuf输出){
内部部分;
while(true){
部分=值&0x7F;
值>>=7;
如果(值!=0){
部分|=0x80;
}
输出写字节(部分);
如果(值==0){
打破
}
}
}
私有最终包类型;
@Getter@Setter私有int-id;
公共定义数据包(数据包类型){
this.type=type;
}
公共数据包(){
返回类型;
}
公开摘要无效书写(ByteBuf buf);
公开摘要无效阅读(ByteBuf buf);

您能为我们提供完整的课程吗

@Override
public void initChannel(SocketChannel channel) {
    ChannelPipeline pipeline = channel.pipeline();

    pipeline.addLast(new LengthFieldPrepender(2));
    pipeline.addLast(new PacketEncoder());

    pipeline.addLast(new LengthFieldBasedFrameDecoder(Short.MAX_VALUE, 0, 2, 0, 2));
    pipeline.addLast(new PacketDecoder());

    pipeline.addLast(new ClientHandler(client));
}
?


将客户端传递给ClientHandler的构造函数后,您从哪里获得
client

我已经解决了这个问题。事实证明,这是在数据包的新实例被解码后处理它们的方式的问题(即对同一数据包的每个实例重用同一对象);DR这个问题可能是完整且可验证的,但它肯定不是最小的:ClientHandler中使用客户机将客户机重新连接到服务器;注册处理程序时,客户端被传递给初始值设定项。我确信这是框架程序的问题,因为我在没有客户端重新连接的情况下对其进行了测试,仍然得到相同的结果。@Henry you写道“当两个客户端同时连接时,我从两个客户端获得相同的数据,而数据应该是不同的。”哪些数据完全相同?相同的
定义数据包
?如果一个客户端连接,一切正常?当一个客户端连接时一切正常,但是当两个客户端同时连接时,定义的数据包数据是相同的。每个客户端定义的数据包数据应该不同。问题似乎不在您提供的代码中。用于两个不同的
SocketChannel
的两个管道正在创建彼此独立的管道,但共享组件
新的ClientHandler(客户端)
除外。我只能指出,
ClientHandler
在处理收到的
DefinedPacket
过程中出现了问题。
@Override
public void initChannel(SocketChannel channel) {
    ChannelPipeline pipeline = channel.pipeline();

    pipeline.addLast(new LengthFieldPrepender(2));
    pipeline.addLast(new PacketEncoder());

    pipeline.addLast(new LengthFieldBasedFrameDecoder(Short.MAX_VALUE, 0, 2, 0, 2));
    pipeline.addLast(new PacketDecoder());

    pipeline.addLast(new ClientHandler(client));
}