netty--helloword程序
2024-09-06 04:33:36
1、使用netty需要使用到下面的java包
netty-all-5.0.0.Alpha2.jar
我们来看下面具体的代码
1. 创建一个ServerBootstrap实例
2. 创建一个EventLoopGroup来处理各种事件,如处理链接请求,发送接收数据等。
3. 定义本地InetSocketAddress( port)好让Server绑定
4. 创建childHandler来处理每一个链接请求
5. 所有准备好之后调用ServerBootstrap.bind()方法绑定Server
package bhz.netty.test; 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; public class Server { public static void main(String[] args) throws Exception {
//1 第一个线程组 是用于接收Client端连接的 ,第一个线程也叫boss线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
//2 第二个线程组 是用于实际的业务处理操作的,第二个线程组也叫worker
EventLoopGroup workerGroup = new NioEventLoopGroup(); //3 创建一个辅助类Bootstrap,就是对我们的Server进行一系列的配置
ServerBootstrap b = new ServerBootstrap();
//把俩个工作线程组加入到Bootstrap中进来
b.group(bossGroup, workerGroup)
//我要指定使用NioServerSocketChannel这种类型的通道,不同的协议这里通道配置不一样
.channel(NioServerSocketChannel.class)
//一定要使用 childHandler 去绑定具体的 事件处理器
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
//通过channel的方法,把ServerHandler添加进去
sc.pipeline().addLast(new ServerHandler());
}
});
//还可以配置channel的缓冲区大小等 //绑定指定的端口 进行监听,这里必须调用sync()是异步操作
ChannelFuture f = b.bind(8765).sync(); //Thread.sleep(1000000);
//为了让服务器端程序一直运行,不会停止,等价于/Thread.sleep(1000000);
f.channel().closeFuture().sync(); bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully(); } }
package bhz.netty.test; /*
*注意所以的包都必须是netty的
*/
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; public class ServerHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //do something msg
ByteBuf buf = (ByteBuf)msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println("Server: " + request);
//写给客户端
String response = "我是反馈的信息";
ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes())).;
//.addListener(ChannelFutureListener.CLOSE); } @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} }
客户端对应的代码:
package bhz.netty.test; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
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; public class Client { public static void main(String[] args) throws Exception {
//客户端不需要boss线程组,只需要worker线程组就可以
EventLoopGroup workgroup = new NioEventLoopGroup();
//服务器端对应的ServerBootstrap
Bootstrap b = new Bootstrap();
b.group(workgroup)
//服务器端对应的是NioServerSocketChannel
.channel(NioSocketChannel.class)
//服务器端对应的是childhandle
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new ClientHandler());
}
}); //ChannelFuture异步非阻塞的通道
ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync(); //buf
cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes())); cf1.channel().closeFuture().sync();
workgroup.shutdownGracefully(); }
}
package bhz.netty.test; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; public class ClientHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//do something msg
ByteBuf buf = (ByteBuf)msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println("Client: " + request); } finally {
ReferenceCountUtil.release(msg);
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
第二个需要注意的地方
客户端多次调用write函数发送数据,但是最后才调用flush,server端收到的数据如下,server端只会收到一次数据,数据如下
所以在编写程序代码的时候,最好使用writeAndFlush()
第三个需要注意的地方
服务端收到客户端发送的数据,需要把数据回复给客户端,这里可以添加一个监听,监听客户端是否收到了服务器发送的数据,监听到客户端收到数据之后,服务端会主动关闭客户端和服务器端建立的连接,客户端的连接就没有了,但是服务器一直还运行
上述代码还有一个更简单的书写形式
在服务端的ServerHandle代码中添加
注意上面的操作是放在服务端中,如果放在客户端中,客户端把数据发送给服务器之后,如果客户端就调用上面的函数,当监听到服务器收到了客户端的数据之后,客户端就主动把连接关闭掉了,就会导致服务器端回复给客户端的数据客户端无法获取到。
最新文章
- git review出现的问题
- js替换字符串问题
- 2014 Super Training #6 B Launching the Spacecraft --差分约束
- vrrp两用
- 09day2
- linux nginx安装
- [topcoder]IncreasingSubsequences
- asp.net 图片质量压缩(不改变尺寸)
- html简单样式
- Spring配置DataSource数据源
- Kotlin入门第三课:数据类型
- unity中object 对象之间用c# delegate方式进行通信
- webpack打包不识别es6语法的坑
- Rails里rake db:migrate出现undefined method last_comment问题的解决
- .net core Swagger 过滤部分Api
- redis初步入门(1)
- C#部分类与部分方法
- 第三次Sprint
- ylz 开发学习笔记一(注意事项)
- java方法中增加不固定参数
热门文章
- dell5460笔记本电脑ubuntu18.04系统音频驱动的安装和使用
- 怎样实现登录?| Cookie or JWT
- Rocket - tilelink - BusWrapper
- InnoSetup汉化版打包工具下载-附带脚本模板
- (Java实现) 洛谷 P1042 乒乓球
- (Java实现) 洛谷 P1691 有重复元素的排列问题
- Java实现 LeetCode 522 最长特殊序列 II(查找最长的非子序列的长度)
- Java实现回文判断
- 基于Azure IoT开发.NET物联网应用系列-全新的Azure IoT架构
- 安装fail2ban,防止ssh爆破及cc攻击