Mina client客户端编写

来源:互联网 发布:中国2016年gdp数据 编辑:程序博客网 时间:2024/04/29 00:33

网上看了下 找mina的客户端编码 发现大家都在讲服务端编写 而且都是拷贝来拷贝去 


下面一个是 面向 mina服务端自定义 过滤器的 客户端编码


public class MinaClient {


/**
* @param args
*/
public static void main(String[] args) {
NioSocketConnector connector = new NioSocketConnector();


DefaultIoFilterChainBuilder chain = connector.getFilterChain();
ProtocolCodecFilter objectFilter = new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.forName("UTF-8")));
chain.addLast("objectFilter", objectFilter);


connector.setHandler(new ClientHandler());
connector.setConnectTimeoutCheckInterval(30l);
ConnectFuture cf = connector.connect(new InetSocketAddress("127.0.0.1",
12345));
cf.awaitUninterruptibly();
IoSession session = cf.getSession();
String format = "2";// kv形式
String message = format+ "FundType=01|MerPriv=";
// 如果要测试服务端多次接受数据 打开此注释
message = changeBig(message);
//
byte[] msgArr = message.getBytes();
int len = msgArr.length;// 字节数据长度
System.out.println("长度:" + len);
byte[] lenBytes = intToByteArray(len);// 转成byte数值 其实就是为了 服务端 bufferio.getInt()能取到前四个自己 表示发送报文的长度 研究了半天才搞懂
byte[] data = byteMerger(lenBytes, msgArr);
IoBuffer io = IoBuffer.wrap(data);//这里要用ioBuffer类包装 服务端 自定义的decoder解码器才能获取 
session.write(io);
cf.getSession().getCloseFuture().awaitUninterruptibly();
connector.dispose();


}


public static String changeBig(String message) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < 20; i++) {
s.append(message);
}
return s.toString();
}


// int转byte数组
public static byte[] intToBytes(int n) {
byte[] b = new byte[4];


for (int i = 0; i < 4; i++) {
b[i] = (byte) (n >> (24 - i * 8));
}
return b;
}


// 合并byte数组
public static byte[] byteMerger(byte[] a, byte[] b) {
byte[] returnBytes = new byte[a.length + b.length];
System.arraycopy(a, 0, returnBytes, 0, a.length);
System.arraycopy(b, 0, returnBytes, a.length, b.length);
return returnBytes;
}


public static byte[] intToByteArray(int i) {
byte[] result = new byte[4];
// 由高位到低位
result[0] = (byte) ((i >> 24) & 0xFF);
result[1] = (byte) ((i >> 16) & 0xFF);
result[2] = (byte) ((i >> 8) & 0xFF);
result[3] = (byte) (i & 0xFF);
return result;
}

public static int byteArrayToInt(byte[] bytes) {
int value = 0;
// 由高位到低位
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (bytes[i] & 0x000000FF) << shift;// 往高位游
}
return value;


}


}



关于服务端的核心代码

    @Override
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    int remaining = in.remaining();
    if(remaining<4){//前四位是消息头长度 如果不足4位则消息不完整
    return false;
    }
    //获取前四位消息头 就是本次发送的数据的长度
    int headLen = in.getInt();
    remaining = in.remaining();//去掉头部消息后 缓冲区内容长度
    if(remaining<headLen){//缓冲区内的长度小于消息头传来的长度 还没传输完 继续等待 最后会默认加一个(byte)10 所以要-1
    in.position(0);//重置position=0 下次继续从头解析
    return false;
    }
    byte formatInt = in.get();//格式类型
    System.out.println("恭喜消息已经传递完毕,长度"+(remaining));
    CharsetDecoder decoder = charset.newDecoder();
    String body = in.getString(headLen-1, decoder);//不需要format
    System.out.println("消息内容:"+body);
    Format format = Format.getFormatByValue(readFormatType(formatInt));//获取format


    Packet packet = new Packet();
        packet.setBody(format.getPacketParser()
                .parse(new ByteArrayInputStream(body.getBytes())));


        out.write(packet);
        return true;
    }
public static int byteArrayToInt(byte[] bytes) {
int value = 0;
// 由高位到低位
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (bytes[i] & 0x000000FF) << shift;// 往高位游
}
return value;


}
private int readFormatType(byte type){
return Integer.valueOf(String.valueOf((char)type));
}


就是这样 如果你想自定义编码解码器 可以这么做 如果你要使用mina自带的 倒不用上面的做法

原创粉丝点击