Mina工具类
jopen
12年前
package com.cucpay.tradeportal.util; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.future.ReadFuture; import org.apache.mina.core.service.IoConnector; 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.filter.codec.ProtocolDecoderAdapter; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import org.apache.mina.filter.codec.ProtocolEncoderAdapter; import org.apache.mina.filter.codec.ProtocolEncoderOutput; import org.apache.mina.transport.socket.nio.NioSocketConnector; /** * 使用Mina2.x发送报文的工具类 * @create Oct 3, 2012 12:42:21 PM * @author 玄玉<http://blog.csdn/net/jadyer> * @version v1.1 * @history v1.1-->编码器和解码器中的字符处理,升级为Mina2.x提供的<code>putString()</code>方法来处理 */ public class MinaUtil { private MinaUtil(){} /** * 发送TCP消息 * @see default timeout of the connect is 1 minute * @see 该方法与远程主机间通信的协议报文为"GB18030"编码后的byte[] * @param message 待发送报文的中文字符串形式 * @param ipAddress 远程主机的IP地址 * @param port 远程主机的端口号 * @return 远程主机响应报文的字符串形式,若对方未响应or响应为null则返回<code>""</code>空字符串 */ public static String sendTCPMessage(String message, String ipAddress, int port){ IoConnector connector = new NioSocketConnector(); connector.setHandler(new ClientHandler(message)); connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new DefaultEncode(TradeCode.CHARSET_BUSIPLATFORM.toString()), new DefaultDecode(TradeCode.CHARSET_BUSIPLATFORM.toString()))); ConnectFuture connectFuture = connector.connect(new InetSocketAddress(ipAddress, port)); connectFuture.awaitUninterruptibly(); //等待连接成功,相当于将异步执行转为同步执行 IoSession session = connectFuture.getSession(); //获取连接成功后的会话对象 session.getConfig().setUseReadOperation(true); //设置IoSession的read()方法为可用,默认为false ReadFuture readFuture = session.read(); //因其内部使用BlockingQueue,故Server端用之可能会内存泄漏,但Client端可适当用之 readFuture.awaitUninterruptibly(); //Wait until the message is received Object respData = readFuture.getMessage(); //Get the received message return respData==null ? "":respData.toString(); //Returns the received message } private static class ClientHandler extends IoHandlerAdapter { private String message; public ClientHandler(String message){ this.message = message; } @Override public void sessionOpened(IoSession session) throws Exception { session.write(message); //ClientHandler会将message传到DefaultEncode,然后将报文发出 } @Override public void messageReceived(IoSession session, Object message) throws Exception { session.close(false); //关闭IoSession,该操作是异步的,true为立即关闭,false为所有写操作都flush后关闭 session.getService().dispose(); //IoSession.close()仅仅是关闭了TCP的连接通道,并未关闭Client端程序 } } private static class DefaultEncode extends ProtocolEncoderAdapter { private final String charset; public DefaultEncode(String charset){ this.charset = charset; } @Override public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { // IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true); // buffer.put(message.toString().getBytes(charset)); // buffer.flip(); //limit=position,position=0 // out.write(buffer); /** * 上面的注释内容,作用效果与下面相同,推荐使用Mina2.x提供的putString() */ IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true); buffer.putString(message.toString(), Charset.forName(charset).newEncoder()); buffer.flip(); out.write(buffer); } } private static class DefaultDecode extends ProtocolDecoderAdapter { private final String charset; public DefaultDecode(String charset){ this.charset = charset; } @Override public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { // if(in.hasArray()){ // System.out.println(LogUtil.formatTenToHexDataWithAscii(in.array(), 0, in.limit())); // } // byte[] len = new byte[6]; //假设报文长度固定为6 // in.get(len, 0, 6); // String msgLen = new String(len); // byte[] body = new byte[Integer.parseInt(msgLen)-6]; // in.get(body); //读取IoBuffer中的所有剩余字节到byte[]中 // String msgBody = new String(body, charset); //报文中可能含中文,故指定解码字符集 // //接收到报文长度-->000158 // //接收到完整报文-->00015800000000订单结果通知:商户系统未成功接收到通知,需要继续通知 4263351542024162852720121019004138201210191` // System.out.println("接收到报文长度-->" + msgLen); // System.out.println("接收到完整报文-->" + msgLen + msgBody); // out.write(msgLen + msgBody); /** * 上面的注释内容,作用效果与下面相同,推荐使用Mina2.x提供的putString() */ IoBuffer buffer = IoBuffer.allocate(158)/*.setAutoExpand(true)*/; while(in.hasRemaining()){ //判断position和limit之间是否有元素 buffer.put(in.get()); //get()读取此缓冲区当前position的字节,然后position+1 } buffer.flip(); out.write(buffer.getString(Charset.forName(charset).newDecoder())); } } }来自:http://blog.csdn.net/jadyer/article/details/8088068