一、發現問題
繼續上篇帖子的內容,https://blog.csdn.net/weixin_43599368/article/details/84206351
利用java原生序列化方式來編碼解碼,其餘代碼如下:
RpcClient:
package rpcserver.client;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import rpcserver.common.InputParam;
import rpcserver.common.OriginJava.ClientMessageDecoder;
import rpcserver.common.OriginJava.ClientMessageEncoder;
public class RpcClient {
int port;
String host;
public RpcClient(int port, String host) {
this.port = port;
this.host = host;
}
public void run() {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
// 第一種java原生的序列化方式
.addLast("decoder", new ClientMessageDecoder())
.addLast("encoder", new ClientMessageEncoder())
.addLast(new RpcClientHandler());
}
});
Channel channel = bootstrap.connect(host, port).sync().channel();
for(int i = 0; i < 100; i ++) {
InputParam inputParam = new InputParam();
inputParam.setNum1(i);
inputParam.setNum2(i * 2);
channel.writeAndFlush(inputParam);
System.out.println("client 發送出去的信息是" + inputParam.toString());
}
//從鍵盤讀出一個字符,然後返回它的Unicode碼;目的是等待client接收完消息再退出
System.in.read();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new RpcClient(8080, "127.0.0.1").run();
}
}
RpcClientHandler:
public class RpcClientHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object outputParam) throws Exception {
System.out.println("client接受到的數據是:" + outputParam.toString());
}
}
RpcServer:
package rpcserver.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import rpcserver.common.OriginJava.ServerMessageDecoder;
import rpcserver.common.OriginJava.ServerMessageEncoder;
public class RpcServer {
private int port;
public RpcServer(int port) {
this.port = port;
}
public void run() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
// 第一種java原生的序列化方式
.addLast("decoder", new ServerMessageDecoder())
.addLast("encoder", new ServerMessageEncoder())
.addLast(new RpcServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = serverBootstrap.bind(port).sync();
f.channel().closeFuture().sync();
} catch (Exception e) {
System.out.println("RpcServer error:" + e);
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
System.out.println("RpcServer 關閉了");
}
}
public static void main(String[] args) {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new RpcServer(port).run();
}
}
RpcServerHandler:
public class RpcServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
InputParam inputParam = (InputParam) msg;
System.out.println("server 接受到的數據是 " + inputParam.toString());
OutputParam outputParam = new OutputParam();
outputParam.setStr1("第一個數是:"+String.valueOf(inputParam.getNum1()));
outputParam.setStr2("第二個數是:"+String.valueOf(inputParam.getNum2()));
ctx.writeAndFlush(outputParam);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
運行
client連續發送2條數據,運行結果如下:
而client發送100條數據,卻出現問題:
server端接收到13條就報錯,懷疑發生了tcp粘包與拆包。
二、