您的位置:首页 > 理论基础 > 计算机网络

Mina Dump:网络协议调试

2016-06-05 19:06 453 查看
ProtocolCodecFilter: An IoFilter  which translates binary or protocol specific data into   message objects and vice versa 。

在解码过程中遇到异常,会把异常的这段字节序保存下来。

@Override
public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
LOGGER.debug("Processing a MESSAGE_RECEIVED for session {}", session.getId());

if (!(message instanceof IoBuffer)) {
nextFilter.messageReceived(session, message);
return;
}

IoBuffer in = (IoBuffer) message;
ProtocolDecoder decoder = factory.getDecoder(session);
ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter);

// Loop until we don't have anymore byte in the buffer,
// or until the decoder throws an unrecoverable exception or
// can't decoder a message, because there are not enough
// data in the buffer
while (in.hasRemaining()) {
//在解码前,把当前位置记录下来
int oldPos = in.position();
try {
synchronized (decoderOut) {
// Call the decoder with the read bytes
decoder.decode(session, in, decoderOut);
}

// Finish decoding if no exception was thrown.
decoderOut.flush(nextFilter, session);
} catch (Throwable t) {
ProtocolDecoderException pde;
if (t instanceof ProtocolDecoderException) {
pde = (ProtocolDecoderException) t;
} else {
pde = new ProtocolDecoderException(t);
}

if (pde.getHexdump() == null) {
// Generate a message hex dump
//当异常出现时,把解码前到当前位置的网络字节序保存下来。生成16进制字符串。
int curPos = in.position();
in.position(oldPos);
pde.setHexdump(in.getHexDump());
in.position(curPos);
}

// Fire the exceptionCaught event.
decoderOut.flush(nextFilter, session);
nextFilter.exceptionCaught(session, pde);

// Retry only if the type of the caught exception is
// recoverable and the buffer position has changed.
// We check buffer position additionally to prevent an
// infinite loop.
if (!(t instanceof RecoverableProtocolDecoderException) || (in.position() == oldPos)) {
break;
}
}
}
}


IoBufferHexDumper: Provides utility methods to dump an  IoBuffer  into a hex formatted string.

class IoBufferHexDumper {

/**
* The high digits lookup table.
*/
private static final byte[] highDigits;

/**
* The low digits lookup table.
*/
private static final byte[] lowDigits;

/**
* Initialize lookup tables.
*/
static {
final byte[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

int i;
byte[] high = new byte[256];
byte[] low = new byte[256];

for (i = 0; i < 256; i++) {
high[i] = digits[i >>> 4];
low[i] = digits[i & 0x0F];
}

highDigits = high;
lowDigits = low;
}

/**
* Dumps an {@link IoBuffer} to a hex formatted string.
*
* @param in the buffer to dump
* @param lengthLimit the limit at which hex dumping will stop
* @return a hex formatted string representation of the <i>in</i> {@link Iobuffer}.
*/
public static String getHexdump(IoBuffer in, int lengthLimit) {
if (lengthLimit == 0) {
throw new IllegalArgumentException("lengthLimit: " + lengthLimit + " (expected: 1+)");
}

boolean truncate = in.remaining() > lengthLimit;
int size;
if (truncate) {
size = lengthLimit;
} else {
size = in.remaining();
}

if (size == 0) {
return "empty";
}

StringBuilder out = new StringBuilder(size * 3 + 3);

int mark = in.position();

// fill the first
int byteValue = in.get() & 0xFF;
out.append((char) highDigits[byteValue]);
out.append((char) lowDigits[byteValue]);
size--;
//把每一个字节变成16进制。并且用空格隔开,这样容易阅读。
// and the others, too
for (; size > 0; size--) {
out.append(' ');
byteValue = in.get() & 0xFF;
out.append((char) highDigits[byteValue]);
out.append((char) lowDigits[byteValue]);
}

in.position(mark);

if (truncate) {
out.append("...");
}

return out.toString();
}
}


在netty中,ByteBufUtil中存在

public static String hexDump(ByteBuf buffer, int fromIndex, int length)

public static String hexDump(byte[] array, int fromIndex, int length)

可以把ByteBuf和Array转换成16进制。

在JsonObjectDecoder 和SniHandler 等在异常情况下把网络字节序dump下来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mina dump