本文链接:https://blog.csdn.net/MCpang/article/details/38613857
https://www.cnblogs.com/JAYIT/p/7027533.html
https://www.cnblogs.com/GoQC/p/6137160.html
https://www.oschina.net/question/3441191_2280569
待测试:
String lines =
"床前明月光\r\n疑是地上霜\r\n举头望明月\r\n低头思故乡\r\n"
;
byte
[] outputBytes = lines.getBytes(
"UTF-8"
);
out.write(outputBytes);
out.flush();
这个没测试成功:
客户端:
-
//客户端通道和尝试连接的帮助类
-
bootstrap = new ClientBootstrap(
-
new NioClientSocketChannelFactory(
-
Executors.newCachedThreadPool(),
-
Executors.newCachedThreadPool()));
-
//配置一个子channel pipeline
-
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
-
public ChannelPipeline getPipeline() {
-
ChannelPipeline pipeline = Channels.pipeline();
-
pipeline.addLast("decoder", new StringDecoder());
-
pipeline.addLast("encoder", new StringEncoder());
-
pipeline.addLast("handler", new LogClientHandler());
-
return pipeline;
-
}
-
});
-
// 配置channel的选项集
-
bootstrap.setOption("tcpNoDelay", true);
-
bootstrap.setOption("keepAlive", false);
-
//连接超时时间为3s
-
bootstrap.setOption("connectTimeoutMillis", 3000);
LogClientHandler没有什么特别的处理。
服务端:
-
//接受传入连接的帮助类
-
bootstrap = new ServerBootstrap(
-
new NioServerSocketChannelFactory(
-
Executors.newCachedThreadPool(),
-
Executors.newCachedThreadPool()));
-
//配置一个子channel pipeline
-
//每个channel都会拥有自己的ChannelPipeline
-
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
-
public ChannelPipeline getPipeline() {
-
ChannelPipeline pipeline = Channels.pipeline();
-
pipeline.addLast("decoder", new StringDecoder());
-
pipeline.addLast("encoder", new StringEncoder());
-
//处理业务逻辑的帮组类
-
pipeline.addLast("handler", new LogServerHandler());
-
return pipeline;
-
}
-
});
-
//配置通道
-
// 子channel的属性集
-
//设置缓存区大小20M
-
bootstrap.setOption("child.receiveBufferSize", 1048576*20);
-
bootstrap.setOption("child.keepAlive", false);
-
bootstrap.setOption("child.tcpNoDelay", true);
-
//创建一个绑定到指定的本地地址的channel
-
bootstrap.bind(configInet(host, port));
LogServerHandler中messageReceived(ChannelHandlerContext ctx, MessageEvent e)直接接受客户端发送的字符串。
netty中在传送字符串的长度有限制,貌似超过1024个字节就截断了,导致接收的信息部完整,经查阅后可采用传送字节数组的方式来解决这个问题:
1、首先在客户端、服务端将转码、解码的方式修改成如下:
pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
pipeline.addLast("encoder", new LengthFieldPrepender(4, false));
2、客户端传送字符串时需要这样:
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(log.getBytes(ConstantSet.CHAR_DECODER));
//当与远程端建立连接以后即刻发送日志信息
channel.write(buffer);
buffer.clear();
3、服务端接收字符串:
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
//添加到日志队列中
ChannelBuffer buffer = (ChannelBuffer)e.getMessage();
String log = buffer.toString(Charset.forName(ConstantSet.CHAR_DECODER));
}
注:上述的字符串与字节数组转换时,采用的字符集编码请保持一致。