Mina deCode里断点 IoBuffer的POS就变了
问题是:我如果在MessageDeCoderClass的decode方法的第一行,打断点,查看发现inBuffer的pos=4,导致我后面的数据全部取错.
然后,我将断点去掉.发现最后就进了正确的commandService 处理类里面.
请教为什么decode里需的pos有时候不是0呢?
用mina写了服务器,大概如下:
mina配置-server.xml:
<bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor" init-method="bind" destroy-method="unbind"> <property name="defaultLocalAddress" value=":10001" /> <property name="handler" ref="serverHandler" /> <property name="reuseAddress" value="true" /> <property name="filterChainBuilder" ref="filterChainBuilder" /> </bean> ...<bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter"> <constructor-arg> <bean class="dc.rpc.handler.MessageCoderFactory"/> </constructor-arg> </bean><bean id="filterChainBuilder" class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder"> <property name="filters"> <map> <entry key="executor" value-ref="executorFilter"/><entry key="mdcInjectionFilter" value-ref="mdcInjectionFilter"/> <entry key="codecFilter" value-ref="codecFilter"/> <entry key="loggingFilter" value-ref="loggingFilter"/> </map> </property> </bean> .....
解码工厂类:
public class MessageCoderFactory extends DemuxingProtocolCodecFactory{ public MessageCoderFactory(){ super.addMessageDecoder(MessageDeCoderClass.class); super.addMessageEncoder(Message.class, MessageEnCoderClass.class); } }
MessageDeCoderClass:
public MessageDecoderResult decodable(IoSession session, IoBuffer buffer) { if(buffer.remaining() < Constant.MSG_HEAD_LENGTH)// 长量=8 return MessageDecoderResult.NEED_DATA; return MessageDecoderResult.OK; }
public MessageDecoderResult decode(IoSession session, IoBuffer inBuffer, ProtocolDecoderOutput out)throws Exception { try{ if(!isReadHead){ head = new MessageHead(); head.setMsgLength(inBuffer.getInt()); //与客户端沟通先发送长度,再发指令ID head.setCommandId(inBuffer.getInt()); } if(inBuffer.remaining() < head.getMsgLength()-Constant.MSG_HEAD_LENGTH) return MessageDecoderResult.NEED_DATA; byte[] byteArray = new byte[head.getMsgLength()-Constant.MSG_HEAD_LENGTH]; inBuffer.get(byteArray); isReadHead = false; out.write(new Message(head,IoBuffer.wrap(byteArray))); return MessageDecoderResult.OK; }catch(Exception e){ e.printStackTrace(); return null; }
Message.class
public class Message implements Serializable { private static final long serialVersionUID = 1L; /** 通信消息头部信息,用于验证,和转发消息用. 定长 */ private MessageHead msgHead; /** 通信消息主体,不定长二进制流 */ private IoBuffer msgBody; ......getter & setter... }
MessageHead类:
public class MessageHead { /**消息总长度 HeadLength+bodyLength */ private int msgLength; /** 指令ID */ private int commandId; ....getter &setter.....
Handler类:
public void messageReceived(IoSession session, Object message) throws Exception { Message requestMsg = (Message) message; CommandServerInter commandService = (CommandServerInter) AppContextUtil.getCtx().getBean("loginCommand"); if(commandService == null){ return; } commandService.requestDeal(session, requestMsg); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在decode中,读取完head时,没有将
isReadHead设为true,导致
if
(inBuffer.remaining() < head.getMsgLength()-Constant.MSG_HEAD_LENGTH)
在decode中,读取完head时,没有将
isReadHead设为true,导致
if
(inBuffer.remaining() < head.getMsgLength()-Constant.MSG_HEAD_LENGTH)