java - 如何在 Java 中追加数据包?

标签 java server netty packet

我有一个简单的客户端/服务器系统构建 Netty我使用数据包发送数据。 一个Packet就我而言,有两种方法可以从 BytBuf 写入和读取。 例如,包含字符串的数据包从字符串中获取字节并将它们写入 ByteBuf ,然后发送,或者从 ByteBuf 读取字节并创建消息。 这是我的数据包接口(interface)的代码片段:

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 .

解码时也会发生同样的情况,只是相反。

我希望事情能这么清楚。

最佳答案

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

例如

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;
    }
}

关于java - 如何在 Java 中追加数据包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56304773/

相关文章:

java - 从google搜索获取html源代码

javascript - 由于多个请求,对 Node.js 服务器的请求超时

postgresql - 在 odoo 中升级时自定义模块卡住

scala - Netty版本与Spark + Elasticsearch Transport冲突

json - JBoss Netty 与 JSON

java - 自定义异常是检查异常还是非检查异常?

java - 15, 11 汉明码发生器矩阵

java - 用于向大量客户端实时分发小消息的 Netty 选项?

JavaFX - 需要通过初始化预填充字段,但不允许异常(exception)。有什么办法解决这个问题吗?

c - 使用线程的多用户 IRC 服务器