Skip to content

Commit 5392c34

Browse files
committed
付政委 bugstack虫洞栈 更新1-09 1-10
1 parent ff5f6a9 commit 5392c34

File tree

17 files changed

+706
-0
lines changed

17 files changed

+706
-0
lines changed

itstack-demo-netty-1-09/pom.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>itstack-demo-netty</artifactId>
7+
<groupId>org.itatack.demo</groupId>
8+
<version>1.0.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>itstack-demo-netty-1-09</artifactId>
13+
14+
<dependencies>
15+
<!-- fastjson -->
16+
<dependency>
17+
<groupId>com.alibaba</groupId>
18+
<artifactId>fastjson</artifactId>
19+
<version>1.2.58</version>
20+
</dependency>
21+
</dependencies>
22+
23+
</project>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package org.itstack.demo.netty.codec;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.channel.ChannelHandlerContext;
5+
import io.netty.handler.codec.ByteToMessageDecoder;
6+
7+
import java.nio.charset.Charset;
8+
import java.util.List;
9+
10+
/**
11+
* 自定义解码器
12+
* 虫洞栈:https://bugstack.cn
13+
* 公众号:bugstack虫洞栈 {关注获取学习源码}
14+
* 虫洞群:①群5398358 ②群5360692
15+
* Create by fuzhengwei on 2019
16+
*/
17+
public class MyDecoder extends ByteToMessageDecoder {
18+
19+
//数据包基础长度
20+
private final int BASE_LENGTH = 4;
21+
22+
@Override
23+
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
24+
25+
//基础长度不足,我们设定基础长度为4
26+
if (in.readableBytes() < BASE_LENGTH) {
27+
return;
28+
}
29+
30+
int beginIdx; //记录包头位置
31+
32+
while (true) {
33+
// 获取包头开始的index
34+
beginIdx = in.readerIndex();
35+
// 标记包头开始的index
36+
in.markReaderIndex();
37+
// 读到了协议的开始标志,结束while循环
38+
if (in.readByte() == 0x02) {
39+
break;
40+
}
41+
// 未读到包头,略过一个字节
42+
// 每次略过,一个字节,去读取,包头信息的开始标记
43+
in.resetReaderIndex();
44+
in.readByte();
45+
// 当略过,一个字节之后,
46+
// 数据包的长度,又变得不满足
47+
// 此时,应该结束。等待后面的数据到达
48+
if (in.readableBytes() < BASE_LENGTH) {
49+
return;
50+
}
51+
52+
}
53+
54+
//剩余长度不足可读取数量[没有内容长度位]
55+
int readableCount = in.readableBytes();
56+
if (readableCount <= 1) {
57+
in.readerIndex(beginIdx);
58+
return;
59+
}
60+
61+
//长度域占4字节,读取int
62+
ByteBuf byteBuf = in.readBytes(1);
63+
String msgLengthStr = byteBuf.toString(Charset.forName("GBK"));
64+
int msgLength = Integer.parseInt(msgLengthStr);
65+
66+
//剩余长度不足可读取数量[没有结尾标识]
67+
readableCount = in.readableBytes();
68+
if (readableCount < msgLength + 1) {
69+
in.readerIndex(beginIdx);
70+
return;
71+
}
72+
73+
ByteBuf msgContent = in.readBytes(msgLength);
74+
75+
//如果没有结尾标识,还原指针位置[其他标识结尾]
76+
byte end = in.readByte();
77+
if (end != 0x03) {
78+
in.readerIndex(beginIdx);
79+
return;
80+
}
81+
82+
out.add(msgContent.toString(Charset.forName("GBK")));
83+
}
84+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.itstack.demo.netty.codec;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.channel.ChannelHandlerContext;
5+
import io.netty.handler.codec.MessageToByteEncoder;
6+
7+
/**
8+
* 自定义编码器
9+
* 虫洞栈:https://bugstack.cn
10+
* 公众号:bugstack虫洞栈 {关注获取学习源码}
11+
* 虫洞群:①群5398358 ②群5360692
12+
* Create by fuzhengwei on 2019
13+
*/
14+
public class MyEncoder extends MessageToByteEncoder {
15+
16+
@Override
17+
protected void encode(ChannelHandlerContext channelHandlerContext, Object in, ByteBuf out) throws Exception {
18+
19+
String msg = in.toString();
20+
byte[] bytes = msg.getBytes();
21+
22+
byte[] send = new byte[bytes.length + 2];
23+
System.arraycopy(bytes, 0, send, 1, bytes.length);
24+
send[0] = 0x02;
25+
send[send.length - 1] = 0x03;
26+
27+
out.writeInt(send.length);
28+
out.writeBytes(send);
29+
30+
}
31+
32+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.itstack.demo.netty.server;
2+
3+
import io.netty.channel.ChannelInitializer;
4+
import io.netty.channel.socket.SocketChannel;
5+
import org.itstack.demo.netty.codec.MyDecoder;
6+
import org.itstack.demo.netty.codec.MyEncoder;
7+
8+
import java.nio.charset.Charset;
9+
10+
/**
11+
* 虫洞栈:https://bugstack.cn
12+
* 公众号:bugstack虫洞栈 {关注获取学习源码}
13+
* 虫洞群:①群5398358 ②群5360692
14+
* Create by fuzhengwei on 2019
15+
*/
16+
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
17+
18+
@Override
19+
protected void initChannel(SocketChannel channel) {
20+
//自定义解码器
21+
channel.pipeline().addLast(new MyDecoder());
22+
//自定义编码器
23+
channel.pipeline().addLast(new MyEncoder());
24+
//在管道中添加我们自己的接收数据实现方法
25+
channel.pipeline().addLast(new MyServerHandler());
26+
}
27+
28+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.itstack.demo.netty.server;
2+
3+
import io.netty.channel.ChannelHandlerContext;
4+
import io.netty.channel.ChannelInboundHandlerAdapter;
5+
import io.netty.channel.socket.SocketChannel;
6+
7+
import java.text.SimpleDateFormat;
8+
import java.util.Date;
9+
10+
/**
11+
* 虫洞栈:https://bugstack.cn
12+
* 公众号:bugstack虫洞栈 {关注获取学习源码}
13+
* 虫洞群:①群5398358 ②群5360692
14+
* Create by fuzhengwei on 2019
15+
*/
16+
public class MyServerHandler extends ChannelInboundHandlerAdapter {
17+
18+
@Override
19+
public void channelActive(ChannelHandlerContext ctx) throws Exception {
20+
SocketChannel channel = (SocketChannel) ctx.channel();
21+
System.out.println("链接报告开始 {公众号:bugstack虫洞栈 >获取学习源码}");
22+
System.out.println("链接报告信息:有一客户端链接到本服务端");
23+
System.out.println("链接报告IP:" + channel.localAddress().getHostString());
24+
System.out.println("链接报告Port:" + channel.localAddress().getPort());
25+
System.out.println("链接报告完毕");
26+
}
27+
28+
@Override
29+
public void channelRead(ChannelHandlerContext ctx, Object msg) {
30+
//接收msg消息{与上一章节相比,此处已经不需要自己进行解码}
31+
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);
32+
33+
ctx.writeAndFlush("hi I'm ok");
34+
}
35+
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.itstack.demo.netty.server;
2+
3+
import io.netty.bootstrap.ServerBootstrap;
4+
import io.netty.channel.ChannelFuture;
5+
import io.netty.channel.ChannelOption;
6+
import io.netty.channel.EventLoopGroup;
7+
import io.netty.channel.nio.NioEventLoopGroup;
8+
import io.netty.channel.socket.nio.NioServerSocketChannel;
9+
10+
/**
11+
* 虫洞栈:https://bugstack.cn
12+
* 公众号:bugstack虫洞栈 {关注获取学习源码}
13+
* 虫洞群:①群5398358 ②群5360692
14+
* Create by fuzhengwei on 2019
15+
*/
16+
public class NettyServer {
17+
18+
public static void main(String[] args) {
19+
new NettyServer().bing(7397);
20+
}
21+
22+
private void bing(int port) {
23+
//配置服务端NIO线程组
24+
EventLoopGroup parentGroup = new NioEventLoopGroup(); //NioEventLoopGroup extends MultithreadEventLoopGroup Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
25+
EventLoopGroup childGroup = new NioEventLoopGroup();
26+
try {
27+
ServerBootstrap b = new ServerBootstrap();
28+
b.group(parentGroup, childGroup)
29+
.channel(NioServerSocketChannel.class) //非阻塞模式
30+
.option(ChannelOption.SO_BACKLOG, 128)
31+
.childHandler(new MyChannelInitializer());
32+
ChannelFuture f = b.bind(port).sync();
33+
System.out.println("itstack-demo-netty server start done. {关注公众号:bugstack虫洞栈,获取源码}");
34+
f.channel().closeFuture().sync();
35+
} catch (InterruptedException e) {
36+
e.printStackTrace();
37+
} finally {
38+
childGroup.shutdownGracefully();
39+
parentGroup.shutdownGracefully();
40+
}
41+
42+
}
43+
44+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package org.itstack.demo.test;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.buffer.CompositeByteBuf;
5+
import io.netty.buffer.Unpooled;
6+
7+
import java.nio.charset.Charset;
8+
import java.util.Arrays;
9+
10+
/**
11+
* 虫洞栈:https://bugstack.cn
12+
* 公众号:bugstack虫洞栈 {关注获取学习源码}
13+
* 虫洞群:①群5398358 ②群5360692
14+
* Create by fuzhengwei on 2019
15+
*/
16+
public class ApiTest {
17+
18+
public static void main(String[] args) {
19+
20+
ByteBuf in = Unpooled.buffer(5);
21+
byte[] bytes = {2, 50, 104, 105, 3};
22+
in.writeBytes(bytes);
23+
in.readBytes(1);
24+
ByteBuf byteBuf = in.readBytes(1);
25+
26+
System.out.println(byteBuf.toString(Charset.forName("GBK")));
27+
}
28+
29+
public void test_03() {
30+
ByteBuf in = Unpooled.buffer(5);
31+
byte[] bytes = {104, 105, 0x02, 104, 105, 0x03, 104};
32+
in.writeBytes(bytes);
33+
34+
//可读数据大小
35+
int size = in.readableBytes();
36+
37+
//读取到byte
38+
byte[] data = new byte[size];
39+
in.readBytes(data);
40+
41+
int beginIdx = 0, endIdx = 0;
42+
for (int i = 0; i < size; i++) {
43+
if (data[i] == 0x02) {
44+
beginIdx = i;
45+
continue;
46+
}
47+
if (data[i] == 0x03) {
48+
endIdx = i;
49+
break;
50+
}
51+
}
52+
53+
ByteBuf copy = in.copy(beginIdx + 1, endIdx - beginIdx - 1);
54+
int i = copy.readableBytes();
55+
byte[] data2 = new byte[i];
56+
copy.readBytes(data2);
57+
System.out.println(Arrays.toString(data2));
58+
59+
//置位
60+
in.resetReaderIndex();
61+
in.readBytes(endIdx + 1);
62+
63+
//余下数据
64+
int i2 = in.readableBytes();
65+
byte[] data3 = new byte[i2];
66+
in.readBytes(data3);
67+
System.out.println(Arrays.toString(data3));
68+
}
69+
70+
public void test_01() {
71+
ByteBuf in = Unpooled.buffer(5);
72+
byte[] bytes = {104, 105, 0x02, 104, 105, 0x03, 104};
73+
in.writeBytes(bytes);
74+
75+
while (true) {
76+
int i = in.readerIndex();
77+
in.markReaderIndex();
78+
if (in.readByte() == 0x02) {
79+
break;
80+
}
81+
//未读到包头,略过一个字节
82+
in.resetReaderIndex();
83+
in.readByte();
84+
}
85+
86+
//假定我们的数据长度是2
87+
ByteBuf byteBuf = in.readBytes(2);
88+
int size = byteBuf.readableBytes();
89+
byte[] data = new byte[size];
90+
byteBuf.readBytes(data);
91+
in.readByte();
92+
System.out.println(Arrays.toString(data));
93+
94+
//余下数据
95+
int i = in.readableBytes();
96+
byte[] data2 = new byte[i];
97+
in.readBytes(data2);
98+
System.out.println(Arrays.toString(data2));
99+
}
100+
101+
public void test_02() {
102+
/* int size = in.readableBytes();
103+
104+
byte[] data = new byte[size];
105+
in.readBytes(data);
106+
107+
byte begin = data[0]; //开始符02
108+
byte end = data[size - 1];//结束符03
109+
110+
//无开始符,只有结束符,数据丢包
111+
if (begin != 0x02 && end == 0x03){
112+
System.out.println("公众号:bugstack虫洞栈 提示;byteBuf数据,无开始符,只有结束符,数据丢包。");
113+
channelHandlerContext.writeAndFlush("error");
114+
return; //直接返回,不置位指针
115+
}
116+
//有开始符,无结束符号,数据半包。置位指针,接收余下数据
117+
if (begin != 0x02 || end != 0x03) {
118+
in.resetReaderIndex();
119+
System.out.println("公众号:bugstack虫洞栈 提示;byteBuf数据,有开始符,无结束符号,数据半包。置位指针,接收余下数据。");
120+
return;
121+
}
122+
//数据完整,解析处理
123+
System.out.println(JSON.toJSONString(data));
124+
//越过02 03位
125+
ByteBuf copy = in.copy(1, size - 1);
126+
//转换
127+
String msg = copy.toString(Charset.forName("GBK"));
128+
//填充
129+
out.add(msg);*/
130+
}
131+
132+
}

0 commit comments

Comments
 (0)