首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Java中追加数据包?

如何在Java中追加数据包?
EN

Stack Overflow用户
提问于 2019-05-25 20:21:36
回答 2查看 291关注 0票数 1

我有一个使用Netty构建的简单客户机/服务器系统,并且我使用数据包发送数据。在我的例子中,Packet有两个方法来写入和读取BytBuf。例如,包含字符串的数据包从字符串中获取字节,并将其写入ByteBuf,然后发送,或者从ByteBuf读取字节并创建消息。下面是来自我的数据包接口的代码片段:

import io.netty.buffer.ByteBuf;

public abstract class Packet {

    public abstract void read(ByteBuf byteBuf);

    public abstract void write(ByteBuf byteBuf);
}

首先,当接收到数据包时,我想检查是否有附加的数据包,然后我想访问或读取它。

问题在于数据包在接收时的实例化。我可以将第二个包附加到另一个包中,并将其存储在第一个包的本地变量中,但是当我使用Class.newInstance()在服务器端重新创建该包时,它就消失了。

此外,据我所知,Netty的ByteBuf不能读取或编写自己的类。

我唯一的想法是发送多个包,我能避免这种情况吗?

编辑

我使用的数据包系统的定义。

由于没有很好地解释数据包系统,我将简要说明它的作用:

在我的例子中,有一个包包装了ByteBuf。在Netty中,发送数据的唯一方法是以字节的形式将其写入ByteBuf。基于字符串的数据包的示例如下:

package com.sxf.protocol.chat.util.packets;

import io.netty.buffer.ByteBuf;

public class MessagePacket extends Packet {

    private String msg;

    public MessagePacket() {}

    public MessagePacket(String message) {
        this.msg = message;
    }

    @Override
    public void read(ByteBuf byteBuf) {
        byte[] msgBytes = new byte[byteBuf.readInt()];
        byteBuf.readBytes(msgBytes);

        msg = new String(msgBytes);
    }

    @Override
    public void write(ByteBuf byteBuf) {
        byte[] msgBytes = msg.getBytes();

        byteBuf.writeInt(msgBytes.length);
        byteBuf.writeBytes(msgBytes);
    }

    public String getMsg() {
        return msg;
    }
}

在创建Packet时,您必须以String的形式添加消息。在编码过程中,我调用write()并传递通过管道发送的ByteBuf。然后将消息格式化为字节并写入ByteBuf

同样的情况也会发生在解码过程中,反之亦然。

我希望事情变得清晰起来。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-25 21:20:00

我不会创建数据包类。我只会使用BufferedOutputStream手动发送数据,或者如果您想发送整个对象,则使用ObjectOutputStream。您还可以通知遥控器您发送的内容(在附加数据之前发送字符串或任何其他内容)。

例如:

package com.stackoverflow.q56304773;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

public class PacketSender {
    private OutputStream networkStream;
    public void sendObject(Object o,String objInfo) throws IOException {
        try(BufferedOutputStream out=new BufferedOutputStream(getNetworkStream());
                ObjectOutputStream objectSender=new ObjectOutputStream(out);
                PrintWriter infoWriter=new PrintWriter(out)){
            infoWriter.printf("Object:%s", objInfo);
            objectSender.writeObject(o);
        }
    }
    public OutputStream getNetworkStream() {
        return networkStream;
    }
    public void setNetworkStream(OutputStream networkStream) {
        this.networkStream = networkStream;
    }
}


package com.stackoverflow.q56304773;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;

public class PacketResciever {
    private InputStream networkStream;
    public void resv() throws IOException, ClassNotFoundException {
        try(BufferedInputStream in=new BufferedInputStream(getNetworkStream());
                BufferedReader infoReader=new BufferedReader(new InputStreamReader(in))){
            String header=infoReader.readLine();
            String[] splitted=header.split(":");
            switch(splitted[0]) {
                case "Object":
                    handleObject(new ObjectInputStream(in).readObject(),splitted[1]);
                    break;
                //other cases
            }

        }
    }
    private void handleObject(Object readObject,String info) {
        //search for handler and execute it
    }
    public InputStream getNetworkStream() {
        return networkStream;
    }
    public void setNetworkStream(InputStream networkStream) {
        this.networkStream = networkStream;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2019-05-31 06:23:30

我发现一种简单的方法是通过向类添加一个变量和几个方法来将一个包附加到另一个包中,如下所示:

package com.sxf.protocol.chat.util.packets;

import io.netty.buffer.ByteBuf;

public abstract class Packet {

    private Packet attached;

    public abstract void read(ByteBuf byteBuf);

    public abstract void write(ByteBuf byteBuf);

    public final boolean isLinked() {
        return attached != null;
    }

    public final void append(Packet packet) {
        attached = packet;
    }

    public final Packet getAttached() {
        if (isLinked()) {
            return attached;
        }

        throw new NullPointerException("unsafe access to getAttached");
    }
}

使用append(),您可以添加数据包并存储传递的数据包。isLinked()返回数据包是否已附加。getAttached()返回追加的数据包。

在编码器中,您可以检查是否添加了数据包,如果是,只需使用添加的数据包调用encode-method。如下所示:

    if (packet.isLinked()) {
            out.writeBoolean(true);
            encode(ctx, packet.getAttached(), out);
    } else {
            out.writeBoolean(false);
    }

解码器和您的自定义ChannelInboundHandler也是如此。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56304773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档