├── tcp-server.iml
├── target
└── classes
│ ├── Main.class
│ ├── pojo
│ └── User.class
│ ├── org
│ └── wisdom
│ │ ├── client
│ │ ├── TcpClient.class
│ │ ├── TcpClient$1.class
│ │ └── echo
│ │ │ ├── EchoHandler.class
│ │ │ ├── EchoHandler_2_0.class
│ │ │ └── EchoHandler_3_0.class
│ │ ├── server
│ │ ├── TcpServer.class
│ │ ├── TcpServer$1.class
│ │ ├── business
│ │ │ ├── BusinessHandler.class
│ │ │ ├── BusinessHandler_2_0.class
│ │ │ └── BusinessHandler_3_0.class
│ │ ├── decoder
│ │ │ ├── DecoderHandler.class
│ │ │ ├── DecoderHandler_2_0.class
│ │ │ └── DecoderHandler_3_0.class
│ │ └── encoder
│ │ │ ├── EncoderHandler.class
│ │ │ ├── EncoderHandler_2_0.class
│ │ │ └── EncoderHandler_3_0.class
│ │ ├── utils
│ │ ├── ByteUtils.class
│ │ ├── ProtocolUtils.class
│ │ └── ProtocolUtils_2_0.class
│ │ ├── protocol
│ │ ├── TcpProtocol.class
│ │ ├── TcpProtocol_2_0.class
│ │ └── TcpProtocol_3_0.class
│ │ └── dataTransefer
│ │ ├── DTObject.class
│ │ └── DTObject_2_0.class
│ └── log4j.properties
├── .idea
├── misc.xml
├── compiler.xml
├── uiDesigner.xml
└── workspace.xml
├── src
└── main
│ ├── resources
│ └── log4j.properties
│ └── java
│ ├── org
│ └── wisdom
│ │ ├── dataTransefer
│ │ ├── DTObject.java
│ │ └── DTObject_2_0.java
│ │ ├── server
│ │ ├── encoder
│ │ │ ├── EncoderHandler.java
│ │ │ ├── EncoderHandler_2_0.java
│ │ │ └── EncoderHandler_3_0.java
│ │ ├── business
│ │ │ ├── BusinessHandler_2_0.java
│ │ │ ├── BusinessHandler_3_0.java
│ │ │ └── BusinessHandler.java
│ │ ├── decoder
│ │ │ ├── DecoderHandler.java
│ │ │ ├── DecoderHandler_2_0.java
│ │ │ └── DecoderHandler_3_0.java
│ │ └── TcpServer.java
│ │ ├── protocol
│ │ ├── TcpProtocol_2_0.java
│ │ ├── TcpProtocol.java
│ │ └── TcpProtocol_3_0.java
│ │ ├── utils
│ │ ├── ByteUtils.java
│ │ ├── ProtocolUtils.java
│ │ └── ProtocolUtils_2_0.java
│ │ └── client
│ │ ├── echo
│ │ ├── EchoHandler_3_0.java
│ │ ├── EchoHandler_2_0.java
│ │ └── EchoHandler.java
│ │ └── TcpClient.java
│ ├── Main.java
│ └── pojo
│ └── User.java
├── pom.xml
├── README.md
└── logs
└── notify-subscription.log
/tcp-server.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/target/classes/Main.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/Main.class
--------------------------------------------------------------------------------
/target/classes/pojo/User.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/pojo/User.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/client/TcpClient.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/client/TcpClient.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/TcpServer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/TcpServer.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/utils/ByteUtils.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/utils/ByteUtils.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/client/TcpClient$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/client/TcpClient$1.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/TcpServer$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/TcpServer$1.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/protocol/TcpProtocol.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/protocol/TcpProtocol.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/utils/ProtocolUtils.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/utils/ProtocolUtils.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/client/echo/EchoHandler.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/client/echo/EchoHandler.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/dataTransefer/DTObject.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/dataTransefer/DTObject.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/utils/ProtocolUtils_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/utils/ProtocolUtils_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/dataTransefer/DTObject_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/dataTransefer/DTObject_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/protocol/TcpProtocol_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/protocol/TcpProtocol_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/protocol/TcpProtocol_3_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/protocol/TcpProtocol_3_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/client/echo/EchoHandler_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/client/echo/EchoHandler_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/client/echo/EchoHandler_3_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/client/echo/EchoHandler_3_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/business/BusinessHandler.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/business/BusinessHandler.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/decoder/DecoderHandler.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/decoder/DecoderHandler.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/encoder/EncoderHandler.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/encoder/EncoderHandler.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/decoder/DecoderHandler_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/decoder/DecoderHandler_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/decoder/DecoderHandler_3_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/decoder/DecoderHandler_3_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/encoder/EncoderHandler_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/encoder/EncoderHandler_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/encoder/EncoderHandler_3_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/encoder/EncoderHandler_3_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/business/BusinessHandler_2_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/business/BusinessHandler_2_0.class
--------------------------------------------------------------------------------
/target/classes/org/wisdom/server/business/BusinessHandler_3_0.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Siwash/netty_TCP/HEAD/target/classes/org/wisdom/server/business/BusinessHandler_3_0.class
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/target/classes/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=debug, ServerDailyRollingFile, stdout
2 | log4j.appender.ServerDailyRollingFile=org.apache.log4j.DailyRollingFileAppender
3 | log4j.appender.ServerDailyRollingFile.DatePattern='.'yyyy-MM-dd
4 | log4j.appender.ServerDailyRollingFile.File=logs/notify-subscription.log
5 | log4j.appender.ServerDailyRollingFile.layout=org.apache.log4j.PatternLayout
6 | log4j.appender.ServerDailyRollingFile.layout.ConversionPattern=%d - %m%n
7 | log4j.appender.ServerDailyRollingFile.Append=true
8 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
9 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
10 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p [%c] %m%n
11 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=debug, ServerDailyRollingFile, stdout
2 | log4j.appender.ServerDailyRollingFile=org.apache.log4j.DailyRollingFileAppender
3 | log4j.appender.ServerDailyRollingFile.DatePattern='.'yyyy-MM-dd
4 | log4j.appender.ServerDailyRollingFile.File=logs/notify-subscription.log
5 | log4j.appender.ServerDailyRollingFile.layout=org.apache.log4j.PatternLayout
6 | log4j.appender.ServerDailyRollingFile.layout.ConversionPattern=%d - %m%n
7 | log4j.appender.ServerDailyRollingFile.Append=true
8 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
9 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
10 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p [%c] %m%n
11 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/dataTransefer/DTObject.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.dataTransefer;
2 |
3 | import java.util.Arrays;
4 |
5 | /**通过全类名字符串解析成具体的对象
6 | * **/
7 | public class DTObject {
8 | private String className;
9 | private byte[] object;
10 |
11 | @Override
12 | public String toString() {
13 | return "DTObject{" +
14 | "className='" + className + '\'' +
15 | ", object=" + Arrays.toString(object) +
16 | '}';
17 | }
18 |
19 | public String getClassName() {
20 | return className;
21 | }
22 |
23 | public void setClassName(String className) {
24 | this.className = className;
25 | }
26 |
27 | public byte[] getObject() {
28 | return object;
29 | }
30 |
31 | public void setObject(byte[] object) {
32 | this.object = object;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/encoder/EncoderHandler.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.encoder;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.MessageToByteEncoder;
6 | import org.apache.log4j.Logger;
7 | import org.wisdom.protocol.TcpProtocol;
8 |
9 | public class EncoderHandler extends MessageToByteEncoder {
10 | private Logger logger = Logger.getLogger(this.getClass());
11 | protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
12 | if (msg instanceof TcpProtocol){
13 | TcpProtocol protocol = (TcpProtocol) msg;
14 | out.writeByte(protocol.getHeader());
15 | out.writeInt(protocol.getLen());
16 | out.writeBytes(protocol.getData());
17 | out.writeByte(protocol.getTail());
18 | logger.debug("数据编码成功:"+out);
19 | }else {
20 | logger.info("不支持的数据协议:"+msg.getClass()+"\t期待的数据协议类是:"+TcpProtocol.class);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/dataTransefer/DTObject_2_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.dataTransefer;
2 |
3 | import java.util.Arrays;
4 |
5 | /**通过全类名字符串解析成具体的对象
6 | * **/
7 | public class DTObject_2_0 {
8 | private String className;
9 | private T object;
10 |
11 | public DTObject_2_0(String className, T object) {
12 | this.className = className;
13 | this.object = object;
14 | }
15 |
16 | @Override
17 | public String toString() {
18 | return "DTObject_2_0{" +
19 | "className='" + className + '\'' +
20 | ", object=" + object +
21 | '}';
22 | }
23 |
24 | public DTObject_2_0() {
25 | }
26 |
27 | public String getClassName() {
28 | return className;
29 | }
30 |
31 | public void setClassName(String className) {
32 | this.className = className;
33 | }
34 |
35 | public Object getObject() {
36 | return object;
37 | }
38 |
39 | public void setObject(T object) {
40 | this.object = object;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/encoder/EncoderHandler_2_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.encoder;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.MessageToByteEncoder;
6 | import org.apache.log4j.Logger;
7 | import org.wisdom.protocol.TcpProtocol_2_0;
8 | import org.wisdom.protocol.TcpProtocol_3_0;
9 |
10 | public class EncoderHandler_2_0 extends MessageToByteEncoder {
11 | private Logger logger = Logger.getLogger(this.getClass());
12 | protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
13 | if (msg instanceof TcpProtocol_2_0){
14 | TcpProtocol_2_0 protocol = (TcpProtocol_2_0) msg;
15 | out.writeByte(protocol.getHeader());
16 | out.writeByte(protocol.getType());
17 | out.writeInt(protocol.getLen());
18 | out.writeBytes(protocol.getData());
19 | out.writeByte(protocol.getTail());
20 | logger.debug("数据编码成功:"+out);
21 | }else {
22 | logger.info("不支持的数据协议:"+msg.getClass()+"\t期待的数据协议类是:"+ TcpProtocol_2_0.class);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/Main.java:
--------------------------------------------------------------------------------
1 | import com.fasterxml.jackson.core.JsonProcessingException;
2 | import com.fasterxml.jackson.databind.ObjectMapper;
3 | import org.wisdom.utils.ByteUtils;
4 | import pojo.User;
5 |
6 | import java.io.IOException;
7 | import java.util.Date;
8 | import java.util.UUID;
9 |
10 | public class Main {
11 | public static void main(String[] args) throws ClassNotFoundException {
12 | User user = new User();
13 | user.setAge(20);
14 | user.setName("mrfox");
15 | user.setUID(UUID.randomUUID().toString());
16 | user.setBirthday(new Date());
17 | System.out.println(User.class.getName());
18 | Class type=Class.forName(User.class.getName());
19 | ObjectMapper objectMapper = ByteUtils.InstanceObjectMapper();
20 | try {
21 | String value = objectMapper.writeValueAsString(user);
22 | System.out.println(value);
23 | System.out.println(objectMapper.readValue(value.getBytes(),type));
24 | } catch (JsonProcessingException e) {
25 | e.printStackTrace();
26 | } catch (IOException e) {
27 | e.printStackTrace();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/business/BusinessHandler_2_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.business;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.channel.ChannelInboundHandlerAdapter;
7 | import org.apache.log4j.Logger;
8 | import org.wisdom.dataTransefer.DTObject_2_0;
9 | import org.wisdom.utils.ByteUtils;
10 | import pojo.User;
11 |
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | public class BusinessHandler_2_0 extends ChannelInboundHandlerAdapter {
16 | private ObjectMapper objectMapper= ByteUtils.InstanceObjectMapper();
17 | private Logger logger = Logger.getLogger(this.getClass());
18 | @Override
19 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
20 | if (msg instanceof List){
21 | logger.info("这是一个List:"+(List)msg);
22 | }else if (msg instanceof Map){
23 | logger.info("这是一个Map:"+(Map)msg);
24 | }else{
25 | logger.info("这是一个对象:"+msg.getClass().getName());
26 | logger.info("这是一个对象:"+msg);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/business/BusinessHandler_3_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.business;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.channel.ChannelInboundHandlerAdapter;
7 | import org.apache.log4j.Logger;
8 | import org.wisdom.dataTransefer.DTObject_2_0;
9 | import org.wisdom.utils.ByteUtils;
10 | import pojo.User;
11 |
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | public class BusinessHandler_3_0 extends ChannelInboundHandlerAdapter {
16 | private ObjectMapper objectMapper= ByteUtils.InstanceObjectMapper();
17 | private Logger logger = Logger.getLogger(this.getClass());
18 | @Override
19 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
20 | if (msg instanceof List){
21 | logger.info("这是一个List:"+(List)msg);
22 | }else if (msg instanceof Map){
23 | logger.info("这是一个Map:"+(Map)msg);
24 | }else{
25 | logger.info("这是一个对象:"+msg.getClass().getName());
26 | logger.info("这是一个对象:"+msg);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/protocol/TcpProtocol_2_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.protocol;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | *type 0x51 0x52 0x53
7 | * mean: object list map
8 | * */
9 | public class TcpProtocol_2_0 {
10 | private byte header=0x58;
11 | private byte type;
12 | private int len;
13 | private byte [] data;
14 | private byte tail=0x63;
15 |
16 | public byte getHeader() {
17 | return header;
18 | }
19 |
20 | public void setHeader(byte header) {
21 | this.header = header;
22 | }
23 |
24 | public byte getType() {
25 | return type;
26 | }
27 |
28 | public void setType(byte type) {
29 | this.type = type;
30 | }
31 |
32 | public int getLen() {
33 | return len;
34 | }
35 |
36 | public void setLen(int len) {
37 | this.len = len;
38 | }
39 |
40 | public byte[] getData() {
41 | return data;
42 | }
43 |
44 | public void setData(byte[] data) {
45 | this.data = data;
46 | }
47 |
48 | public byte getTail() {
49 | return tail;
50 | }
51 |
52 | public void setTail(byte tail) {
53 | this.tail = tail;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/encoder/EncoderHandler_3_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.encoder;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.MessageToByteEncoder;
6 | import org.apache.log4j.Logger;
7 | import org.wisdom.protocol.TcpProtocol_3_0;
8 |
9 | public class EncoderHandler_3_0 extends MessageToByteEncoder {
10 | private Logger logger = Logger.getLogger(this.getClass());
11 | protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
12 | if (msg instanceof TcpProtocol_3_0){
13 | TcpProtocol_3_0 protocol = (TcpProtocol_3_0) msg;
14 | out.writeByte(protocol.getHeader());
15 | out.writeByte(protocol.getType());
16 | out.writeByte(protocol.getClassLen());
17 | out.writeInt(protocol.getLen());
18 | out.writeBytes(protocol.getClassName());
19 | out.writeBytes(protocol.getData());
20 | out.writeByte(protocol.getTail());
21 | logger.debug("数据编码成功:"+out);
22 | }else {
23 | logger.info("不支持的数据协议:"+msg.getClass()+"\t期待的数据协议类是:"+ TcpProtocol_3_0.class);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/pojo/User.java:
--------------------------------------------------------------------------------
1 | package pojo;
2 |
3 | import io.netty.channel.group.ChannelGroup;
4 |
5 | import java.util.Date;
6 |
7 | public class User {
8 | private String name;
9 | private int age;
10 | private String UID;
11 | private Date birthday;
12 |
13 | @Override
14 | public String toString() {
15 | return "User{" +
16 | "name='" + name + '\'' +
17 | ", age=" + age +
18 | ", UID='" + UID + '\'' +
19 | ", birthday=" + birthday +
20 | '}';
21 | }
22 |
23 | public String getName() {
24 | return name;
25 | }
26 |
27 | public void setName(String name) {
28 | this.name = name;
29 | }
30 |
31 | public int getAge() {
32 | return age;
33 | }
34 |
35 | public void setAge(int age) {
36 | this.age = age;
37 | }
38 |
39 | public String getUID() {
40 | return UID;
41 | }
42 |
43 | public void setUID(String UID) {
44 | this.UID = UID;
45 | }
46 |
47 | public Date getBirthday() {
48 | return birthday;
49 | }
50 |
51 | public void setBirthday(Date birthday) {
52 | this.birthday = birthday;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/utils/ByteUtils.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.utils;
2 |
3 | import com.fasterxml.jackson.databind.DeserializationConfig;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 |
6 | import java.text.SimpleDateFormat;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.TimeZone;
10 |
11 | public class ByteUtils {
12 | private static ObjectMapper objectMapper=new ObjectMapper();
13 | private static List datePattern=new ArrayList();
14 | static {
15 | datePattern.add("yyyy-MM-dd hh/mm/ss");
16 | datePattern.add("yyyy-MM-dd hh:mm:ss");
17 | datePattern.add("yyyy/MM/dd hh:mm:dd");
18 | }
19 | static {
20 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
21 | DeserializationConfig config=objectMapper.getDeserializationConfig();
22 | for (String s : datePattern) {
23 | objectMapper.setDateFormat(new SimpleDateFormat(s));
24 | }
25 | objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
26 | }
27 | public static ObjectMapper InstanceObjectMapper(){
28 | return objectMapper;
29 | }
30 | public List getDatePattern() {
31 | return datePattern;
32 | }
33 |
34 | public void setDatePattern(List datePattern) {
35 | this.datePattern = datePattern;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/client/echo/EchoHandler_3_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.client.echo;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.channel.ChannelInboundHandlerAdapter;
6 | import org.wisdom.protocol.TcpProtocol_3_0;
7 | import org.wisdom.utils.ProtocolUtils;
8 | import pojo.User;
9 |
10 | import java.util.*;
11 |
12 | public class EchoHandler_3_0 extends ChannelInboundHandlerAdapter {
13 |
14 | //连接成功后发送消息测试
15 | @Override
16 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
17 | User user = new User();
18 | user.setBirthday(new Date());
19 | user.setUID(UUID.randomUUID().toString());
20 | user.setName("冉鹏峰");
21 | user.setAge(24);
22 | Map map=new HashMap<>();
23 | map.put("数据一",user);
24 | List users=new ArrayList<>();
25 | users.add(user);
26 | TcpProtocol_3_0 protocol = ProtocolUtils.prtclInstance(map,user.getClass().getName());
27 | //传map
28 | ctx.write(protocol);//由于设置了编码器,这里直接传入自定义的对象
29 | ctx.flush();
30 | //传list
31 | ctx.write(ProtocolUtils.prtclInstance(users,user.getClass().getName()));
32 | ctx.flush();
33 | //传单一实体
34 | ctx.write(ProtocolUtils.prtclInstance(user));
35 | ctx.flush();
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/protocol/TcpProtocol.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.protocol;
2 |
3 | import java.util.Arrays;
4 |
5 | public class TcpProtocol {
6 | private byte header=0x58;
7 | private int len;
8 | private byte [] data;
9 | private byte tail=0x63;
10 |
11 | public byte getTail() {
12 | return tail;
13 | }
14 |
15 | public void setTail(byte tail) {
16 | this.tail = tail;
17 | }
18 |
19 | public TcpProtocol(int len, byte[] data) {
20 | this.len = len;
21 | this.data = data;
22 | }
23 |
24 | public TcpProtocol() {
25 | }
26 |
27 | @Override
28 | public String toString() {
29 | return "TcpProtocol{" +
30 | "header=" + header +
31 | ", len=" + len +
32 | ", data=" + Arrays.toString(data) +
33 | ", tail=" + tail +
34 | '}';
35 | }
36 |
37 | public byte getHeader() {
38 | return header;
39 | }
40 |
41 | public void setHeader(byte header) {
42 | this.header = header;
43 | }
44 |
45 | public int getLen() {
46 | return len;
47 | }
48 |
49 | public void setLen(int len) {
50 | this.len = len;
51 | }
52 |
53 | public byte[] getData() {
54 | return data;
55 | }
56 |
57 | public void setData(byte[] data) {
58 | this.data = data;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/client/echo/EchoHandler_2_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.client.echo;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.channel.ChannelInboundHandlerAdapter;
6 | import org.wisdom.dataTransefer.DTObject_2_0;
7 | import org.wisdom.protocol.TcpProtocol;
8 | import org.wisdom.protocol.TcpProtocol_2_0;
9 | import org.wisdom.utils.ByteUtils;
10 | import org.wisdom.utils.ProtocolUtils_2_0;
11 | import pojo.User;
12 |
13 | import java.util.ArrayList;
14 | import java.util.Date;
15 | import java.util.HashMap;
16 | import java.util.UUID;
17 |
18 | public class EchoHandler_2_0 extends ChannelInboundHandlerAdapter {
19 |
20 | //连接成功后发送消息测试
21 | @Override
22 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
23 | User user = new User();
24 | user.setBirthday(new Date());
25 | user.setUID(UUID.randomUUID().toString());
26 | user.setName("冉鹏峰");
27 | user.setAge(24);
28 | HashMap map = new HashMap<>();
29 | map.put("数据一",user);
30 | map.put("数据2",user);
31 | map.put("数据3",user);
32 | ArrayList list = new ArrayList<>();
33 | list.add(user);
34 | list.add(user);
35 | list.add(user);
36 | list.add(user);
37 | TcpProtocol_2_0 tcpProtocol= ProtocolUtils_2_0.prtclInstance(map,user.getClass().getName());
38 | ctx.write(tcpProtocol);
39 | ctx.flush();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/business/BusinessHandler.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.business;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.channel.ChannelInboundHandlerAdapter;
6 | import org.apache.log4j.Logger;
7 | import org.wisdom.dataTransefer.DTObject;
8 | import org.wisdom.protocol.TcpProtocol;
9 | import org.wisdom.utils.ByteUtils;
10 |
11 | public class BusinessHandler extends ChannelInboundHandlerAdapter {
12 | private ObjectMapper objectMapper= ByteUtils.InstanceObjectMapper();
13 | private Logger logger = Logger.getLogger(this.getClass());
14 | @Override
15 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
16 | if (msg instanceof byte []){
17 | logger.debug("解码后的字节码:"+new String((byte[]) msg,"UTF-8"));
18 | try {
19 | Object objectContainer = objectMapper.readValue((byte[]) msg, DTObject.class);
20 | if (objectContainer instanceof DTObject){
21 | DTObject data = (DTObject) objectContainer;
22 | if (data.getClassName()!=null&&data.getObject().length>0){
23 | Object object = objectMapper.readValue(data.getObject(), Class.forName(data.getClassName()));
24 | logger.info("收到实体对象:"+object);
25 | }
26 | }
27 | }catch (Exception e){
28 | logger.info("对象反序列化出现问题:"+e);
29 | }
30 |
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.wisdom.netty
8 | tcp-server
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 | org.apache.maven.plugins
14 | maven-compiler-plugin
15 |
16 | 7
17 | 7
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | io.netty
26 | netty-all
27 | 4.1.6.Final
28 |
29 |
30 |
31 | com.fasterxml.jackson.core
32 | jackson-databind
33 | 2.9.7
34 |
35 |
36 |
37 | log4j
38 | log4j
39 | 1.2.17
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/utils/ProtocolUtils.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.utils;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import org.wisdom.protocol.TcpProtocol_3_0;
5 |
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public class ProtocolUtils {
10 | public final static byte OBJ_TYPE=0x51;
11 | public final static byte LIST_TYPE=0x52;
12 | public final static byte MAP_TYPE=0x53;
13 | /**
14 | * 创建集合类list map对象
15 | * */
16 | public static TcpProtocol_3_0 prtclInstance(Object o, String className){
17 | TcpProtocol_3_0 protocol = new TcpProtocol_3_0();
18 | if (o instanceof List){
19 | protocol.setType(LIST_TYPE);
20 | }else if (o instanceof Map){
21 | protocol.setType(MAP_TYPE);
22 | }else if (o instanceof Object){
23 | protocol.setType(OBJ_TYPE);
24 | }
25 | initProtocol(o, className, protocol);
26 |
27 | return protocol;
28 | }
29 | /***
30 | *
31 | * 创建单一的对象
32 | */
33 | public static TcpProtocol_3_0 prtclInstance(Object o){
34 | TcpProtocol_3_0 protocol = new TcpProtocol_3_0();
35 | protocol.setType(OBJ_TYPE);
36 | initProtocol(o, o.getClass().getName(), protocol);
37 |
38 | return protocol;
39 | }
40 |
41 | private static void initProtocol(Object o, String className, TcpProtocol_3_0 protocol) {
42 | byte [] classBytes=className.getBytes();
43 | try {
44 | byte [] objectBytes= ByteUtils.InstanceObjectMapper().writeValueAsBytes(o);
45 | protocol.setClassLen((byte) classBytes.length);
46 | protocol.setLen(objectBytes.length);
47 | protocol.setData(objectBytes);
48 | protocol.setClassName(classBytes);
49 | } catch (JsonProcessingException e) {
50 | e.printStackTrace();
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/utils/ProtocolUtils_2_0.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.utils;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import org.wisdom.dataTransefer.DTObject;
5 | import org.wisdom.protocol.TcpProtocol_2_0;
6 | import org.wisdom.protocol.TcpProtocol_3_0;
7 |
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | public class ProtocolUtils_2_0 {
12 | public final static byte OBJ_TYPE=0x51;
13 | public final static byte LIST_TYPE=0x52;
14 | public final static byte MAP_TYPE=0x53;
15 | /**
16 | * 创建集合类list map对象
17 | * */
18 | public static TcpProtocol_2_0 prtclInstance(Object o, String className){
19 | TcpProtocol_2_0 protocol = new TcpProtocol_2_0();
20 | if (o instanceof List){
21 | protocol.setType(LIST_TYPE);
22 | }else if (o instanceof Map){
23 | protocol.setType(MAP_TYPE);
24 | }else if (o instanceof Object){
25 | protocol.setType(OBJ_TYPE);
26 | }
27 | initProtocol(o, className, protocol);
28 |
29 | return protocol;
30 | }
31 | /***
32 | *
33 | * 创建单一的对象
34 | */
35 | public static TcpProtocol_2_0 prtclInstance(Object o){
36 | TcpProtocol_2_0 protocol = new TcpProtocol_2_0();
37 | protocol.setType(OBJ_TYPE);
38 | initProtocol(o, o.getClass().getName(), protocol);
39 |
40 | return protocol;
41 | }
42 |
43 | private static void initProtocol(Object o, String className, TcpProtocol_2_0 protocol) {
44 | try {
45 | DTObject dtObject = new DTObject();
46 | byte [] objectBytes= ByteUtils.InstanceObjectMapper().writeValueAsBytes(o);
47 | dtObject.setObject(objectBytes);
48 | dtObject.setClassName(className);
49 | byte[] bytes = ByteUtils.InstanceObjectMapper().writeValueAsBytes(dtObject);
50 | protocol.setLen(bytes.length);
51 | protocol.setData(bytes);
52 | } catch (JsonProcessingException e) {
53 | e.printStackTrace();
54 | }
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/client/TcpClient.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.client;
2 |
3 | import io.netty.bootstrap.Bootstrap;
4 | import io.netty.channel.Channel;
5 | import io.netty.channel.ChannelFuture;
6 | import io.netty.channel.ChannelInitializer;
7 | import io.netty.channel.ChannelOption;
8 | import io.netty.channel.nio.NioEventLoopGroup;
9 | import io.netty.channel.socket.nio.NioSocketChannel;
10 | import io.netty.handler.logging.LoggingHandler;
11 | import org.wisdom.client.echo.EchoHandler;
12 | import org.wisdom.client.echo.EchoHandler_2_0;
13 | import org.wisdom.client.echo.EchoHandler_3_0;
14 | import org.wisdom.server.encoder.EncoderHandler_2_0;
15 | import org.wisdom.server.encoder.EncoderHandler_3_0;
16 |
17 | public class TcpClient {
18 |
19 | private String ip;
20 | private int port;
21 | public void init() throws InterruptedException {
22 | NioEventLoopGroup group = new NioEventLoopGroup();
23 | try {
24 | Bootstrap bootstrap = new Bootstrap();
25 | bootstrap.group(group);
26 | bootstrap.channel(NioSocketChannel.class);
27 | bootstrap.option(ChannelOption.SO_KEEPALIVE,true);
28 | bootstrap.handler(new ChannelInitializer() {
29 | @Override
30 | protected void initChannel(Channel ch) throws Exception {
31 | ch.pipeline().addLast("logging",new LoggingHandler("DEBUG"));
32 | ch.pipeline().addLast(new EncoderHandler_3_0());
33 | ch.pipeline().addLast(new EchoHandler_3_0());
34 | }
35 | });
36 | bootstrap.remoteAddress(ip,port);
37 | ChannelFuture future = bootstrap.connect().sync();
38 |
39 | future.channel().closeFuture().sync();
40 | } catch (InterruptedException e) {
41 | e.printStackTrace();
42 | }finally {
43 | group.shutdownGracefully().sync();
44 | }
45 | }
46 |
47 | public TcpClient(String ip, int port) {
48 | this.ip = ip;
49 | this.port = port;
50 | }
51 |
52 | public static void main(String[] args) throws InterruptedException {
53 | new TcpClient("127.0.0.1",8777).init();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/client/echo/EchoHandler.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.client.echo;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.channel.ChannelInboundHandlerAdapter;
6 | import org.wisdom.dataTransefer.DTObject;
7 | import org.wisdom.protocol.TcpProtocol;
8 | import org.wisdom.utils.ByteUtils;
9 | import pojo.User;
10 |
11 | import java.util.Arrays;
12 | import java.util.Date;
13 | import java.util.UUID;
14 |
15 | public class EchoHandler extends ChannelInboundHandlerAdapter {
16 |
17 | //连接成功后发送消息测试
18 | @Override
19 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
20 | User user = new User();
21 | user.setBirthday(new Date());
22 | user.setUID(UUID.randomUUID().toString());
23 | user.setName("冉鹏峰");
24 | user.setAge(24);
25 | DTObject dtObject = new DTObject();
26 | dtObject.setClassName(user.getClass().getName());
27 | dtObject.setObject(ByteUtils.InstanceObjectMapper().writeValueAsBytes(user));
28 | TcpProtocol tcpProtocol = new TcpProtocol();
29 | byte [] objectBytes=ByteUtils.InstanceObjectMapper().writeValueAsBytes(dtObject);
30 | tcpProtocol.setLen(objectBytes.length);
31 | tcpProtocol.setData(objectBytes);
32 | ByteBuf buffer = ctx.alloc().buffer();
33 | buffer.writeByte(tcpProtocol.getHeader());
34 | buffer.writeInt(tcpProtocol.getLen());
35 | buffer.writeBytes(Arrays.copyOfRange(tcpProtocol.getData(),0,tcpProtocol.getLen()/2));
36 |
37 | ctx.write(buffer);
38 | ctx.flush();
39 | Thread.sleep(3000);
40 | buffer = ctx.alloc().buffer();
41 | buffer.writeBytes(Arrays.copyOfRange(tcpProtocol.getData(),tcpProtocol.getLen()/2,tcpProtocol.getLen()));
42 | buffer.writeByte(tcpProtocol.getTail());
43 | //模拟粘包的第二帧数据
44 | buffer.writeByte(tcpProtocol.getHeader());
45 | buffer.writeInt(tcpProtocol.getLen());
46 | buffer.writeBytes(tcpProtocol.getData());
47 | buffer.writeByte(tcpProtocol.getTail());
48 | //模拟粘包的第三帧数据
49 | buffer.writeByte(tcpProtocol.getHeader());
50 | buffer.writeInt(tcpProtocol.getLen());
51 | buffer.writeBytes(tcpProtocol.getData());
52 | buffer.writeByte(tcpProtocol.getTail());
53 | ctx.write(buffer);
54 | ctx.flush();
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/wisdom/server/decoder/DecoderHandler.java:
--------------------------------------------------------------------------------
1 | package org.wisdom.server.decoder;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.channel.ChannelHandlerContext;
5 | import io.netty.handler.codec.ByteToMessageDecoder;
6 | import org.apache.log4j.Logger;
7 |
8 | import java.util.Arrays;
9 | import java.util.List;
10 |
11 | public class DecoderHandler extends ByteToMessageDecoder {
12 | //最小的数据长度:开头标准位1字节
13 | private static int MIN_DATA_LEN=6;
14 | //数据解码协议的开始标志
15 | private static byte PROTOCOL_HEADER=0x58;
16 | //数据解码协议的结束标志
17 | private static byte PROTOCOL_TAIL=0x63;
18 | private Logger logger = Logger.getLogger(this.getClass());
19 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List