一、定义协议实体

 

 


1. import java.nio.charset.Charset;  
2.   
3. /** 
4.  * 自定义协议的消息体 
5.  */  
6. public class MyMsg {  
7. /** 
8.      * 消息长度 
9.      */  
10. private Integer lenth;  
11.   
12. /** 
13.      * 发送人 
14.      */  
15. private Long sender;  
16.   
17. /** 
18.      * 接收人 
19.      */  
20. private Long receiver;  
21.   
22. /** 
23.      * 消息内容 
24.      */  
25. private String content;  
26.       
27. public MyMsg() {  
28.           
29.     }  
30.   
31. public Long getSender() {  
32. return sender;  
33.     }  
34.   
35. public void setSender(Long sender) {  
36. this.sender = sender;  
37.     }  
38.   
39. public Long getReceiver() {  
40. return receiver;  
41.     }  
42.   
43. public void setReceiver(Long receiver) {  
44. this.receiver = receiver;  
45.     }  
46.   
47. public String getContent() {  
48. return content;  
49.     }  
50.   
51. public void setContent(String content) {  
52. this.content = content;  
53.     }  
54.   
55. /** 
56.      * 先计算长度,再返回。这里长度包含长度本身的字节 
57.      */  
58. public Integer getLenth() {  
59.           
60. this.lenth = 4 + 8*2 + this.content.getBytes(Charset.forName("utf-8")).length;  
61.           
62. return lenth;  
63.     }  
64.   
65. public MyMsg(Long sender, Long receiver, String content) {  
66. this.sender = sender;  
67. this.receiver = receiver;  
68. this.content = content;  
69.     }  
70.   
71. @Override  
72. public String toString() {  
73. return "MyMsg [lenth=" + this.getLenth() + ", sender=" + sender + ", receiver="  
74. ", content=" + content + "]";  
75.     }  
76.   
77. }

二、定义编解码器

 

    1、编码器

 

 


1. import java.nio.charset.Charset;  
2. import java.nio.charset.CharsetEncoder;  
3. import org.apache.mina.core.buffer.IoBuffer;  
4. import org.apache.mina.core.session.IoSession;  
5. import org.apache.mina.filter.codec.ProtocolEncoderAdapter;  
6. import org.apache.mina.filter.codec.ProtocolEncoderOutput;  
7.   
8. /** 
9.  *  编码器  
10.  */  
11. public class MyEncoder extends ProtocolEncoderAdapter {  
12.   
13. @Override  
14. public void encode(IoSession session, Object message, ProtocolEncoderOutput encoderOutput)  
15. throws Exception {  
16.   
17. "utf-8").newEncoder();  
18.           
19.         MyMsg msg = (MyMsg) message;  
20.           
21. //  Mina IoBuffer  
22. 100).setAutoExpand(true);  
23.           
24.         buffer.putInt(msg.getLenth());  
25.         buffer.putLong(msg.getSender());  
26.         buffer.putLong(msg.getReceiver());  
27.           
28. //  有多个可变长度的属性时,可约定通过定义可变属性的最大长度(多余截取不足补齐)或put之前put其长度等方式处理  
29.         buffer.putString(msg.getContent(), ce);  
30.           
31.         buffer.flip();  
32.           
33.         encoderOutput.write(buffer);  
34.           
35.     }  
36.   
37. }

    2、解码器

 

 

 


1. import java.nio.charset.Charset;  
2. import java.nio.charset.CharsetDecoder;  
3. import org.apache.mina.core.buffer.IoBuffer;  
4. import org.apache.mina.core.session.IoSession;  
5. import org.apache.mina.filter.codec.CumulativeProtocolDecoder;  
6. import org.apache.mina.filter.codec.ProtocolDecoderOutput;  
7.   
8. /** 
9.  *  解码器可继承ProtocolEncoderAdapter,但它不利于处理粘包的情况 
10.  */  
11. public class MyDecoder extends CumulativeProtocolDecoder {  
12.       
13. @Override  
14. protected boolean doDecode(IoSession session, IoBuffer buffer, ProtocolDecoderOutput decoderOutput)   
15. throws Exception {  
16. "utf-8").newDecoder();  
17.   
18. /** 
19.          * 这里,如果长度不够20字节,就认为这条消息还没有累积完成 
20.          */  
21. if(buffer.remaining() < 20){  
22. /** 
23.              *      停止调用decode,但如果还有数据没有读取完,将含有剩余数据的IoBuffer保存到IoSession中, 
24.              *  当有新数据包来的时候再和新的合并后再调用decoder解码 
25.              *      注意:没有消费任何数据时不能返回true,否则会抛出异常 
26.              */  
27. return false;  
28.               
29. else{  
30.               
31. int length = buffer.getInt();  
32.               
33. new MyMsg();  
34.               
35.             msg.setSender(buffer.getLong());  
36.             msg.setReceiver(buffer.getLong());  
37.               
38. //  注意:20 = 消息长度的字节 + 发送人和接收人的字节  
39. 20, de));  
40.               
41.             decoderOutput.write(msg);  
42.               
43. /** 
44.              *  CumulativeProtocolDecoder会再次调用decoder,并把剩余的数据发下来继续解码 
45.              */  
46. return true;  
47.         }  
48.     }  
49.   
50. }

    3、编解码工厂

 

 

[java] view plain copy

 


1. import org.apache.mina.core.session.IoSession;  
2. import org.apache.mina.filter.codec.ProtocolCodecFactory;  
3. import org.apache.mina.filter.codec.ProtocolDecoder;  
4. import org.apache.mina.filter.codec.ProtocolEncoder;  
5.   
6. /** 
7.  *  编解码工厂 
8.  */  
9. public class MyCoderFactory implements ProtocolCodecFactory{  
10.       
11. private MyDecoder decoder;  
12. private MyEncoder encoder;  
13.   
14. public MyCoderFactory() {  
15. this.decoder = new MyDecoder();  
16. this.encoder = new MyEncoder();  
17.     }  
18.   
19. @Override  
20. public ProtocolDecoder getDecoder(IoSession session) throws Exception {  
21. return decoder;  
22.     }  
23.   
24. @Override  
25. public ProtocolEncoder getEncoder(IoSession session) throws Exception {  
26. return encoder;  
27.     }  
28.   
29. }

三、服务器端

 

    1、运行类

 

[java] view plain copy

 


1. import java.io.IOException;  
2. import .InetSocketAddress;  
3. import .SocketAddress;  
4. import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;  
5. import org.apache.mina.core.service.IoAcceptor;  
6. import org.apache.mina.core.session.IdleStatus;  
7. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
8. import org.apache.mina.filter.logging.LoggingFilter;  
9. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
10.   
11. public class ServerMain {  
12.       
13. public static void main(String[] args) throws IOException {  
14.           
15. //  在服务器端创建一个监听连接的接收器 基于tcp/ip  
16. new NioSocketAcceptor();  
17.           
18. //  绑定的端口  
19. new InetSocketAddress("localhost", 8888);  
20.           
21. //   获取过滤器链  
22.         DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();  
23.           
24. //  添加日志过滤器  
25. "logger", new LoggingFilter());  
26.           
27. // 配置自定义的编解码器   
28. "mycodec", new ProtocolCodecFilter(new MyCoderFactory()));  
29.           
30. //  添加数据处理的处理器  
31. new ServerHandler());  
32.           
33. //  进行配置信息的设置       
34. 100);       
35. 10);   
36.           
37. //  绑定服务器端口   
38.         acceptor.bind(address);  
39.           
40. "服务器开始在 8888 端口监听.......");  
41.           
42.     }  
43. }

    2、Handler

 

 

[java] view plain copy

 

1. import org.apache.mina.core.service.IoHandlerAdapter;  
2. import org.apache.mina.core.session.IdleStatus;  
3. import org.apache.mina.core.session.IoSession;  
4.   
5. public class ServerHandler extends IoHandlerAdapter{  
6.   
7. /** 
8.      *  接受消息 
9.      */  
10. public void messageReceived(IoSession session, Object message)  
11. throws Exception {  
12.         MyMsg msg = (MyMsg) message;  
13. "服务器端接收到的消息:" + msg);  
14.           
15. //  返回一个消息给客户端  
16. new MyMsg(10000L, 10001L, "你好,这是来自服务器的应答!");  
17.         session.write(msg);  
18.     }  
19.   
20. /** 
21.      *  发送消息 
22.      */  
23. public void messageSent(IoSession session, Object message) throws Exception {  
24. "服务器端开始发送消息...");  
25. super.messageSent(session, message);  
26.     }  
27.   
28. /** 
29.      *  会话开启 
30.      */  
31. public void sessionOpened(IoSession session) throws Exception {  
32. "服务端会话已打开...");  
33. super.sessionOpened(session);  
34.     }  
35.   
36. /** 
37.      *  异常处理 
38.      */  
39. public void exceptionCaught(IoSession session, Throwable cause)  
40. throws Exception {  
41. "服务端发生异常了...");  
42.         cause.printStackTrace();  
43.     }  
44.   
45. /** 
46.      *  会话关闭 
47.      */  
48. public void sessionClosed(IoSession session) throws Exception {  
49. "服务端会话已关闭...");  
50. super.sessionClosed(session);  
51.     }  
52.   
53. /** 
54.      *  会话创建 
55.      */  
56. public void sessionCreated(IoSession session) throws Exception {  
57. "服务端会话已创建...");  
58. super.sessionCreated(session);  
59.     }  
60.   
61. /** 
62.      *  连接空闲 
63.      */  
64. public void sessionIdle(IoSession session, IdleStatus status)  
65. throws Exception {  
66. "服务端连接空闲中...");  
67. super.sessionIdle(session, status);  
68.     }  
69. }

四、客户端

 

    1、连接类

 

[java] view plain copy

 


1. import .InetSocketAddress;  
2. import .SocketAddress;  
3. import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;  
4. import org.apache.mina.core.future.ConnectFuture;  
5. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
6. import org.apache.mina.filter.logging.LoggingFilter;  
7. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
8.   
9. public class ClientMain {  
10. public static void main(String[] args) {  
11.           
12. //  创建客户端连接器 基于tcp/ip  
13. new NioSocketConnector();  
14.           
15. //  连接的地址和端口  
16. new InetSocketAddress("localhost",8888);  
17.   
18. //  获取过滤器链  
19.         DefaultIoFilterChainBuilder chain = connector.getFilterChain();  
20.       
21. //  配置日志过滤器和自定义编解码器  
22. "logger", new LoggingFilter());  
23. "mycodec",new ProtocolCodecFilter(new MyCoderFactory()));  
24.       
25. //  添加处理器  
26. new ClientHandler());  
27.           
28. // 连接到服务器   
29.         ConnectFuture future = connector.connect(address);  
30.       
31. //  等待连接创建完成  
32.         future.awaitUninterruptibly();  
33.           
34. //  会话创建后发送消息到服务器  
35. new MyMsg(10001L, 10000L, "你好,这是来自客户端的请求!");  
36.         future.getSession().write(msg);  
37.       
38. //  等待28000毫秒后连接断开  
39. 28000);  
40.   
41. //  关闭连接  
42.         connector.dispose();  
43.       
44.     }  
45. }

    2、Handler

 

 

[java] view plain copy

 

1. import org.apache.mina.core.service.IoHandlerAdapter;  
2. import org.apache.mina.core.session.IoSession;  
3.   
4. public class ClientHandler extends IoHandlerAdapter{  
5.   
6. /** 
7.      *  接收消息 
8.      */  
9. public void messageReceived(IoSession session, Object message)  
10. throws Exception {  
11. "客户端接收到的消息:" + (MyMsg)message);  
12.     }  
13.   
14. /** 
15.      *  发送消息 
16.      */  
17. public void messageSent(IoSession session, Object message) throws Exception {  
18. "客户端发送消息...");  
19. super.messageSent(session, message);  
20.           
21.     }  
22.   
23. /** 
24.      *  会话创建 
25.      */  
26. public void sessionOpened(IoSession session) throws Exception {  
27.           
28. "客户端已经连接到了服务器...");  
29.           
30.     }  
31.   
32. /** 
33.      *  会话关闭 
34.      */  
35. public void sessionClosed(IoSession session) throws Exception {  
36. "连接关闭...");  
37. super.sessionClosed(session);  
38.     }  
39.       
40. }

五、结果

    1、服务器端

        

java消息订阅实现 java自定义消息协议_apache

    2、客户端

        

java消息订阅实现 java自定义消息协议_java消息订阅实现_02