怎样使用Java网络通讯框架Mina自定义消息格式
需要我们自定义CodeFilter来实现自有协议的解析和发送
----------------
一般来说在开发网络的C/S应用中,我们如果想从一长串字节流中得到我们要的数据并组织成业务上的pojo,我们一般用以下几种方法:
1、采用固定长度的message
2、用固定的头标示body的长度
3、用基于文本的标示,如换行、回车等
我们基于前两种方式的会比较多一些。
下面是Mina官方的一个例子:
首先定义一下网络协议采用TCP/IP协议,客户端发送的消息的格式如下:
4 bytes 4 bytes 4 bytes
width height numchars
开头4个字节是一个图片的宽度,中间4个字节是图片的高度,最后4个字节是图片中字符的数量,我们可以暂且认为这是个图片验证码的小demo。
服务端发回给客户端的就是图片,图片是通过字节流的方式发过来的,消息体如下:
4 bytes variable length body 4 bytes variable length body
【怎样使用Java网络通讯框架Mina自定义消息格式】 length1 image1 length2 image2
开头的四个字节代表第一张图片的长度,然后是图片的具体内容,然后是第二张图片的长度和第二张图片的具体内容。
然后定义两个实体,用来封装服务端的响应和客户端的请求:
import java.net.InetSocketAddress;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.transport.socket.SocketConnector;import org.apache.mina.transport.socket.nio.NioSocketConnector;public class ImageClient extends IoHandlerAdapter {\tpublic static final int CONNECT_TIMEOUT = 3000;\tprivate String host;\tprivate int port;\tprivate SocketConnector connector;\tprivate IoSession session;\tprivate ImageListener imageListener;\tpublic ImageClient() {\t\tthis("127.0.0.1", 33789, new ImageListener());\t}\tpublic ImageClient(String host, int port, ImageListener imageListener) {\t\tthis.host = host;\t\tthis.port = port;\t\tthis.imageListener = imageListener;\t\tconnector = new NioSocketConnector();\t\tconnector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ImageCodecFactory(true)));\t\tconnector.setHandler(this);\t\t// 连接到特定的remote地址,InetSocketAddress封装IP和port,Java网络编程规范,\t\t// 不提供直接的ip地址和端口的connect方法\t\tConnectFuture connectFuture = connector.connect(new InetSocketAddress(this.host, this.port));\t\t// 等待建立连接\t\tconnectFuture.awaitUninterruptibly();\t\tSystem.out.println("连接成功");\t\t// 返回代表两端连接的一个对象,有读写方法以及获取本端网络设置的相关方法\t\tthis.session = connectFuture.getSession();\t\tsession.write(new ImageRequest(4, 4, 100));\t}\tpublic void messageReceived(IoSession session, Object message) throws Exception {\t\tImageResponse response = (ImageResponse) message;\t\timageListener.onImages(response.getImage1(), response.getImage2());\t}\tpublic static void main(String args) {\t\tnew ImageClient();\t}}import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFactory;import org.apache.mina.filter.codec.ProtocolDecoder;import org.apache.mina.filter.codec.ProtocolEncoder;public class ImageCodecFactory implements ProtocolCodecFactory {\tprivate ProtocolEncoder encoder;\tprivate ProtocolDecoder decoder;\tpublic ImageCodecFactory(boolean client) {\t\tif (client) {\t\t\tencoder = new ImageRequestEncoder();\t\t\tdecoder = new ImageResponseDecoder();\t\t} else {\t\t\tencoder = new ImageResponseEncoder();\t\t\tdecoder = new ImageRequestDecoder();\t\t}\t}\tpublic ProtocolEncoder getEncoder(IoSession ioSession) throws Exception {\t\treturn encoder;\t}\tpublic ProtocolDecoder getDecoder(IoSession ioSession) throws Exception {\t\treturn decoder;\t}}
推荐阅读
- 聪明人养花,这3种“花”怎样也要养一盆,每年能省不少医药费
- 『先进』长江流域最先进洗舱站在宁投运 油可分离回收,水能循环使用
- 互联网怎样解决“家政服务上门速度慢”的问题
- 怎样看待从1月8号起,QQ钱包开始提现收费
- 银行it人怎样转型
- 汽车|冬天怎样让车内温度快速升高?座椅加热的最佳使用方式二,外循环的作用总结
- 怎样进入通信行业
- 怎样评价扶他柠檬茶的小说《云养汉》的结尾
- 汽车|迈凯伦Artura不再使用迈凯伦祖传V8引擎了?
- 怎样成为一名合格的Python程序员?
