Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
下面编写四个类
1.用于接收数据的服务器端Socket
2.用于接收客户端的消息,用于接收和反馈客户端发出的消息类ServertHandler
3.用于发送数据的服务器端Client
4.用于发送数据和接收服务器端发出的数据处理类ClientHandler
1.用于接收数据的服务器端Socket
2.用于接收客户端的消息,用于接收和反馈客户端发出的消息类ServertHandler
3.用于发送数据的服务器端Client
4.用于发送数据和接收服务器端发出的数据处理类ClientHandler
简单的了解几个类:
EventLoop 这个相当于一个处理线程,是Netty接收请求和处理IO请求的线程。
ServerBootstrap 从命名上看就可以知道,这是一个对服务端做配置和启动的类。
ChannelPipeline 这是Netty处理请求的责任链,这是一个ChannelHandler的链表,而ChannelHandler就是用来处理网络请求的内容的。
ChannelHandler 用来处理网络请求内容,有ChannelInboundHandler和ChannelOutboundHandler两种
引入jar包:
1
<dependency>
2
<groupId>io.netty</groupId>
3
<artifactId>netty-all</artifactId>
4
<version>4.1.1.Final</version>
5
</dependency>
nettyServer:
1
package com.ycb.socket;
2
3
import com.ycb.socket.netty.ServerInitializer;
4
import io.netty.bootstrap.ServerBootstrap;
5
import io.netty.channel.Channel;
6
import io.netty.channel.ChannelOption;
7
import io.netty.channel.EventLoopGroup;
8
import io.netty.channel.nio.NioEventLoopGroup;
9
import io.netty.channel.socket.nio.NioServerSocketChannel;
10
import org.slf4j.Logger;
11
import org.slf4j.LoggerFactory;
12
13
import java.net.InetSocketAddress;
14
15
public class NettyServer {
16
private Logger logger = LoggerFactory.getLogger(getClass());
17
/**
18
* Runtime.getRuntime():返回与当前 Java 应用程序相关的运行时对象。
19
* availableProcessors() : 向 Java 虚拟机返回可用处理器的数目。
20
* 用于分配处理业务线程的线程组个数
21
*/
22
protected static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors() * 2;
23
/**
24
* 业务出现线程大小
25
*/
26
protected static final int BIZTHREADSIZE = 4;
27
/**
28
* 第一个线程组是用于接收Client端连接的
29
*/
30
private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE);
31
/**
32
* 第二个线程组是用于实际的业务处理的
33
*/
34
private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE);
35
//引入下面的类
36
private ServerInitializer initializer;
37
/**
38
* 监听端口
39
*/
40
private final int port;
41
42
public NettyServer(int port) {
43
this.port = port;
44
}
45
46
public void setInitializer(ServerInitializer initializer) {
47
this.initializer = initializer;
48
}
49
50
public void run() throws Exception {
51
52
try {
53
/**
54
* 服务端做配置和启动的类
55
*/
56
ServerBootstrap b = new ServerBootstrap()
57
.group(bossGroup, workerGroup)//绑定两个线程池
58
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
59
.channel(NioServerSocketChannel.class)//指定NIO的模式,如果是客户端就是NioSocketChannel
60
.childHandler(this.initializer);
61
62
this.logger.info(" server started at port " + this.port + '.');
63
Channel ch = b.bind(new InetSocketAddress(this.port)).sync().channel();//绑定端口
64
ch.closeFuture().sync();
65
} finally {
66
bossGroup.shutdownGracefully();
67
workerGroup.shutdownGracefully();
68
}
69
}
70
}
71
上面定义的ServerInitializer:
1
package com.ycb.socket.netty;
2
3
import com.ycb.socket.dispatcher.HandlerDispatcher;
4
import io.netty.channel.ChannelInitializer;
5
import io.netty.channel.ChannelPipeline;
6
import io.netty.channel.socket.SocketChannel;
7
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
8
import io.netty.handler.codec.Delimiters;
9
import io.netty.handler.codec.string.StringDecoder;
10
import io.netty.handler.codec.string.StringEncoder;
11
12
public class ServerInitializer extends ChannelInitializer<SocketChannel> {
13
14
private HandlerDispatcher handlerDispatcher;
15
16
public void init() {
17
new Thread(this.handlerDispatcher).start();
18
}
19
20
public void initChannel(SocketChannel ch) throws Exception {
21
ChannelPipeline pipeline = ch.pipeline();
22
// 以("\n")为结尾分割的 解码器
23
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()));//在管道中加入结束字符串
24
// 字符串解码 和 编码
25
pipeline.addLast("decoder", new StringDecoder());
26
pipeline.addLast("encoder", new StringEncoder());
27
pipeline.addLast("handler", new ServerAdapter(this.handlerDispatcher));
28
}
29
30
public void setHandlerDispatcher(HandlerDispatcher handlerDispatcher) {
31
this.handlerDispatcher = handlerDispatcher;
32
}
33
}