• MINA2中的拆包组包的处理及一些方法


    1.position 

    例: 
    Java代码  收藏代码
    1. position()   

    第一次使用返回值为当前位置:0 


    position(8) 返回第8个字节以后的数据(包括第8个)可以和 limit 联合使用 
    如: 
    Java代码  收藏代码
    1. buffer.position(3);   
    2. buffer.limit(7);   
    3. ByteBuffer slice = buffer.slice();   



    再次调用 position() 返回:8 


    2.remaining 

    例: 

    Java代码  收藏代码
    1. ByteBuffer byt = ByteBuffer.allocate(128,false);   

    第一次调用 
    byt.remaining(); 返回 128 

    A、使用:byt.putInt(5);或者byt.getInt()或者byt.get(字节数组)等方法 

    之后调用 byt.remaining(); 返回 124 

    B、但使用 byt.putInt(5,4);或者byt.getInt(0) 之后,调用方法 
    byt.remaining();返回 128 


    3.prefixedDataAvailable 

    prefixedDataAvailable(4) int 

    该方法很好用。判断前四字节的整型值是否大于等于整个缓冲区的数据。可以方便的判断一次 
    messageReceived 过来的数据是否完整。(前提是自己设计的网络通讯协议前四字节等于发送数据的长度) 

    prefixedDataAvailable(2) Short int 


    网上找到的例子: 

    Java代码  收藏代码
    1. protected boolean doDecode(IoSession session, IoBuffer in,   
    2.            ProtocolDecoderOutput out) throws Exception {   
    3.        if (in.prefixedDataAvailable(4, Constants.MAX_COMMAND_LENGTH)) {   
    4.            int length = in.getInt();   
    5.            byte[] bytes = new byte[length];   
    6.            in.get(bytes);   
    7.            int commandNameLength = Constants.COMMAND_NAME_LENGTH;   
    8.            byte[] cmdNameBytes = new byte[commandNameLength];   
    9.            System.arraycopy(bytes, 0, cmdNameBytes, 0, commandNameLength);   
    10.            String cmdName = (new String(cmdNameBytes)).trim();   
    11.            AbstractTetrisCommand command = TetrisCommandFactory   
    12.                .newCommand(cmdName);   
    13.            if (command != null) {   
    14.                byte[] cmdBodyBytes = new byte[length - commandNameLength];   
    15.                System.arraycopy(bytes, commandNameLength, cmdBodyBytes, 0,   
    16.                    length - commandNameLength);   
    17.                command.bodyFromBytes(cmdBodyBytes);   
    18.                out.write(command);   
    19.            }   
    20.            return true;   
    21.        } else {   
    22.            return false;   
    23.        }   
    24.    }   


    MINA中分段读取数据的方法: 


    2. ProtobufRPCRequestProtocolDecoder.java 

    Java代码  收藏代码
    1. package com.lizongbo.protobufrpc;  
    2.   
    3. import org.apache.mina.filter.codec.ProtocolDecoder;  
    4. import org.apache.mina.core.session.IoSession;  
    5. import org.apache.mina.core.buffer.IoBuffer;  
    6. import org.apache.mina.filter.codec.ProtocolDecoderOutput;  
    7. import org.apache.mina.core.session.AttributeKey;  
    8.   
    9. public class ProtobufRPCRequestProtocolDecoder implements ProtocolDecoder {  
    10.   
    11. private static final AttributeKey BUF_BYTE = new AttributeKey(  
    12. ProtobufRPCRequestProtocolDecoder.class"bufb");  
    13.   
    14. public void decode(IoSession ioSession, IoBuffer ioBuffer,  
    15. ProtocolDecoderOutput protocolDecoderOutput) throws  
    16. Exception {  
    17. try {  
    18. IoBuffer bufTmp = null;  
    19. byte[] buf = (byte[]) ioSession.getAttribute(BUF_BYTE);  
    20. if (buf == null) {  
    21. System.out.println("没有尚未处理的数据" + ioBuffer.remaining());  
    22. bufTmp = ioBuffer;  
    23. else {  
    24. System.out.println("合并尚未处理的数据" + ioBuffer.remaining());  
    25. bufTmp = IoBuffer.allocate(buf.length + ioBuffer.remaining());  
    26. bufTmp.setAutoExpand(true);  
    27. bufTmp.put(buf);  
    28. bufTmp.put(ioBuffer);  
    29. bufTmp.flip();  
    30. while (bufTmp.remaining() >= 4  
    31. && bufTmp.remaining() >= bufTmp.getInt(bufTmp.position())) { // 循环处理数据包  
    32. System.out.println("循环处理数据包");  
    33. int dataLen = bufTmp.getInt(bufTmp.position());  
    34. byte[] b = new byte[dataLen];  
    35. bufTmp.get(b);  
    36. ProtobufRPCRequest pak = new ProtobufRPCRequest();  
    37. pak.setReqByteLen(b.length);  
    38. pak.readFrom(b, 4);  
    39. System.out.println("往下传递");  
    40. protocolDecoderOutput.write(pak);  
    41. }  
    42. if (bufTmp.hasRemaining()) { // 如果有剩余的数据,则放入Session中  
    43. System.out.println("如果有剩余的数据,则放入Session中" + bufTmp.remaining());  
    44. byte[] tmpb = new byte[bufTmp.remaining()];  
    45. bufTmp.get(tmpb);  
    46. ioSession.setAttribute(BUF_BYTE, tmpb);  
    47. }  
    48. catch (Exception ex) {  
    49. ex.printStackTrace();  
    50. }  
    51. }  
    52.   
    53. public void dispose(IoSession session) throws Exception {  
    54. System.out.println("dispose");  
    55.   
    56. }  
    57.   
    58. public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws  
    59. Exception {  
    60. System.out.println("finishDecode");  
    61. }  
    62.   
    63. }  
  • 相关阅读:
    Github使用手册2——Github使用自己的远程仓库
    GitHub使用手册1——fork and pull request
    如何申请Pycharm学生免费激活码
    博客园入园手册2——Markdown编辑器1
    博客园入园手册1——TinyMEC编辑器
    实验一 GIT 代码版本管理
    结对项目-数独程序扩展(要求细化更新)
    个人作业Week2-代码复审(修改明确了要求)
    个人作业-Week1(新增详细说明)
    个人项目-数独
  • 原文地址:https://www.cnblogs.com/balaamwe/p/2319194.html
Copyright © 2020-2023  润新知