TCP スティッキー パケットのアンパックの問題に対処するためにコーデックをカスタマイズする
特定のコードの実装
カスタム コーデック
PersonProtocol
public class PersonProtocol {
プライベート int の長さ。
プライベート byte[] コンテンツ。
public int getLength() { 長さを返します。 }
public void setLength(int length) { this.length = length; }
public byte[] getContent() { コンテンツを返します。 }
public void setContent(byte[] content) { this.content = content; } }
MyPersonDecoder
// 编写解器
public class MypersonDecoder extends ReplayingDecoder<Void> { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { System.out.println("MyPersonDecoder decode invoked!");
int 長 = in.readInt();
byte[] コンテンツ = 新しいバイト[長さ];
in.readBytes(コンテンツ);
パーソンプロトコル personProtocol = 新しい パーソンプロトコル();
personProtocol.setLength(長さ);
personProtocol.setContent(コンテンツ);
out.add(personProtocol);
}
}
MyPersonalEncoder
// エンコーダ
public class MyPersonalEncoder extends MessageToByteEncoder<PersonProtocol> {
@Override
protected void encode(ChannelHandlerContext ctx, PersonProtocol msg, ByteBuf out) throws Exception { 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{
// イベントスレッドグループeventLoopGroup
EventLoopGroupeventLoopGroup = new NioEventLoopGroup();
try { ブートストラップ bootstrap = new Bootstrap(); // 启アニメーション服务 bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class). handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline パイプライン = ch.pipeline();
Pipeline.addLast(new MyPersonEncoder());
Pipeline.addLast(new MyPersonDecoder());
Pipeline.addLast(new MyClientHandler());
}
}); // チャネルの初期化
ChannelFuture channelFuture = bootstrap.connect("localhost",8899).sync();
channelFuture.channel().closeFuture().sync();
}最後に { eventLoopGroup.shutdownGraceful(); } } }
MyClientHandler
public class MyClientHandler extends SimpleChannelInboundHandler<PersonProtocol> {
プライベート int カウント;
@Override
protected void channelRead0(ChannelHandlerContext ctx, PersonProtocol msg) throws Exception {
int length=msg.getLength();
byte[] コンテンツ = msg.getContent();
System.out.println("クライアントがメッセージを受信しました");
System.out.println("長さ:"+length);
System.out.println("内容:"+new String(content, Charset.forName("utf-8")));
System.out.println("クライアントが受信したメッセージの数: "+(++count));
}
@Override
public void channelActive(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.setLength(長さ);
personProtocol.setContent(コンテンツ);
ctx.writeAndFlush(personProtocol); @Override public voidExceptionCaught(ChannelHandlerContext ctx, Throwable Cause) throws Exception {
Cause.printStackTrace (); } } ctx.close(); } }
服务端
MyServer
public class MyServer { public static void main(String[]args) throws Exception{
//2 つのスレッド グループ
EventLoopGroup BossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try { ServerBootstrap serverBootstrap = new ServerBootstrap();// サーバーを起動し ます 。 BossGroup のログ ハンドラー childHandler(new MyServerInitialzer());//workerGroup のログ レベルを指定します
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();//ポートをバインド
channelFuture.channel().closeFuture().sync();
}finally { BossGroup.shutdownGraceful();// スレッド グループを閉じる workGroup.shutdownGraceful ( ); } } }
MyServerInitializer
public class MyServerInitialzer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline パイプライン = ch.pipeline();
Pipeline.addLast(new MyPersonDecoder());
Pipeline.addLast(new MyPersonEncoder());
Pipeline.addLast(new MyServerHandler());
}
}
MyServerHandler
public class MyServerHandler extends SimpleChannelInboundHandler<PersonProtocol> { private int count; @Override protected void channelRead0(ChannelHandlerContext ctx, PersonProtocol msg) throws Exception {
int 長 = msg.getLength();
byte[] コンテンツ = msg.getContent();
System.out.println("サーバーがデータを受信しました:");
System.out.println("Length: "+length);
System.out.println("Content: "+new String (content, Charset.forName( " utf-8")));
System.out.println("サーバーが受信したメッセージの数: "+(++count));
文字列応答メッセージ = UUID.randomUUID().toString();
int responseLength = responseMessage.getBytes("utf-8").length;
byte[] responseContent = responseMessage.getBytes("utf-8");
パーソンプロトコル personProtocol = 新しい パーソンプロトコル();
personProtocol.setContent(responseContent);
personProtocol.setLength(responseLength);
ctx.writeAndFlush(personProtocol);
}
@Override
public voidExceptionCaught(ChannelHandlerContext ctx, Throwable Cause) throws Exception { Cause.printStackTrace(); ctx.close(); } }