Passen Sie den Codec an, um das Problem des Entpackens von TCP-Sticky-Paketen zu lösen
Spezifische Code-Implementierung
Benutzerdefinierter Codec
PersonProtocol
öffentliche Klasse PersonProtocol {
private int-Länge;
privater Byte[]-Inhalt;
public int getLength() { return length; }
public void setLength(int length) { this.length = length; }
öffentliches Byte[] getContent() { return content; }
public void setContent(byte[] content) { this.content = content; } }
MyPersonDecoder
//
Öffentliche Klasse MyPersonDecoder erweitert ReplayingDecoder<Void> { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { System.out.println("MyPersonDecoder decode invoked!");
int length = in.readInt();
byte[] Inhalt = neues Byte[Länge];
in.readBytes(content);
PersonProtocol personProtocol = new PersonProtocol();
personProtocol.setLength(length);
personProtocol.setContent(content);
out.add(personProtocol);
}
}
MyPersonEncoder
// Encoder
öffentliche Klasse MyPersonEncoder erweitert MessageToByteEncoder<PersonProtocol> {
@Override
protected void encode(ChannelHandlerContext ctx, PersonProtocol msg, ByteBuf out) löst eine Ausnahme aus { System.out.println("MyPersonEncoder encode invoked!");
out.writeInt(msg.getLength());
out.writeBytes(msg.getContent());
}
}
服务端
MyClient
public class MyClient { public static void main(String[] args) throws Exception{
// Ereignis-Thread-Gruppe eventLoopGroup
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try { Bootstrap bootstrap = new Bootstrap(); // Füge bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) hinzu. handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline Pipeline= ch.pipeline();
Pipeline.addLast(new MyPersonEncoder());
Pipeline.addLast(new MyPersonDecoder());
Pipeline.addLast(new MyClientHandler());
}
}); // Kanalinitialisierung
ChannelFuture channelFuture = bootstrap.connect("localhost",8899).sync();
channelFuture.channel().closeFuture().sync();
}finally { eventLoopGroup.shutdownGracefully(); } } }
Öffentliche Klasse MyClientHandler
MyClientHandler erweitert SimpleChannelInboundHandler<PersonProtocol> {
private int count;
@Override
protected voidchannelRead0(ChannelHandlerContext ctx, PersonProtocol msg) löst eine Ausnahme aus {
int length=msg.getLength();
byte[] content = msg.getContent();
System.out.println("Der Client hat die Nachricht erhalten");
System.out.println("长度:"+length);
System.out.println("内容:"+new String(content, Charset.forName("utf-8")));
System.out.println("Die Anzahl der vom Client empfangenen Nachrichten: "+(++count));
}
@Override
public voidchannelActive(ChannelHandlerContext ctx) throws Exception { for(int i=0;i<10;i++){ String messageToBeSent = "发送自客户端"; byte[] content = messageToBeSent.getBytes(Charset.forName("utf-8")); int length = messageToBeSent.getBytes(Charset.forName("utf-8")).length;
PersonProtocol personProtocol = new PersonProtocol();
personProtocol.setLength(length);
personProtocol.setContent(content);
ctx.writeAndFlush(personProtocol);
}
}
@Override
public void AusnahmeCaught(ChannelHandlerContext ctx, Throwable Cause) throws Exception { Cause.printStackTrace(); ctx.close(); } }
服务端
MyServer
public class MyServer { public static void main(String[]args) throws Exception{
//Zwei Thread-Gruppen
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try { ServerBootstrap serverBootstrap = new ServerBootstrap();//Starten Sie den Server serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)). //Geben Sie die Protokollebene des an Protokollhandler für BossGroup childHandler(new MyServerInitialzer());//Geben Sie die Protokollebene für workerGroup an
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();//Port binden
channelFuture.channel().closeFuture().sync();
}finally { bossGroup.shutdownGracefully();//Threadgruppe schließen workerGroup.shutdownGracefully ( ); } } }
MyServerInitialzer
öffentliche Klasse MyServerInitialzer erweitert ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipelinepipeline = ch.pipeline();
Pipeline.addLast(new MyPersonDecoder());
Pipeline.addLast(new MyPersonEncoder());
Pipeline.addLast(new MyServerHandler());
}
}
Öffentliche Klasse MyServerHandler MyServerHandler erweitert SimpleChannelInboundHandler<PersonProtocol> { private int count; @Override protected voidchannelRead0(ChannelHandlerContext ctx, PersonProtocol msg) löst eine Ausnahme aus {
int length = msg.getLength();
byte[] content = msg.getContent();
System.out.println("Der Server hat die Daten empfangen:");
System.out.println("Length: "+length);
System.out.println("Content: "+new String (content, Charset.forName( "utf-8")));
System.out.println("Die Anzahl der vom Server empfangenen Nachrichten: "+(++count));
String ResponseMessage= UUID.randomUUID().toString();
int ResponseLength = ResponseMessage.getBytes("utf-8").length;
byte[] ResponseContent = ResponseMessage.getBytes("utf-8");
PersonProtocol personProtocol = new PersonProtocol();
personProtocol.setContent(responseContent);
personProtocol.setLength(responseLength);
ctx.writeAndFlush(personProtocol);
}
@Override
public void AusnahmeCaught(ChannelHandlerContext ctx, Throwable Cause) löst eine Ausnahme aus { Cause.printStackTrace(); ctx.close(); } }