我有一个使用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
。反之,在解码时也会发生同样的情况。
我希望事情变得如此清楚。
最佳答案
我不会创建Packet类。如果要发送整个对象,我将只使用BufferedOutputStream
手动发送数据,或者使用ObjectOutputStream
。您还可以将发送的内容告知远程设备(在附加数据之前发送String或其他任何内容)。
例如
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;
}
}