All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.acgist.snail.net.torrent.PeerUnpackMessageCodec Maven / Gradle / Ivy

package com.acgist.snail.net.torrent;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;

import com.acgist.snail.net.codec.MessageCodec;
import com.acgist.snail.net.torrent.peer.bootstrap.PeerSubMessageHandler;
import com.acgist.snail.system.config.PeerConfig;
import com.acgist.snail.system.config.SystemConfig;
import com.acgist.snail.system.exception.NetException;
import com.acgist.snail.system.exception.PacketSizeException;

/**
 * 

Peer消息处理器:拆包

* * TODO:握手消息匹配协议名称 * * @author acgist * @since 1.1.0 */ public final class PeerUnpackMessageCodec extends MessageCodec { /** * int字符长度 */ private static final int INT_BYTE_LENGTH = 4; /** *

完整消息缓存

*

消息按照长度读入进入消息缓存

*/ private ByteBuffer buffer; /** * 消息长度 */ private final ByteBuffer lengthStick; /** * Peer代理 */ private final PeerSubMessageHandler peerSubMessageHandler; public PeerUnpackMessageCodec(PeerSubMessageHandler peerSubMessageHandler) { super(peerSubMessageHandler); this.lengthStick = ByteBuffer.allocate(INT_BYTE_LENGTH); this.peerSubMessageHandler = peerSubMessageHandler; } @Override public void decode(ByteBuffer buffer, InetSocketAddress address, boolean haveAddress) throws NetException { int length = 0; // 消息数据长度 while(true) { if(this.buffer == null) { if(this.peerSubMessageHandler.handshake()) { for (int index = 0; index < buffer.limit() && buffer.hasRemaining(); index++) { this.lengthStick.put(buffer.get()); if(this.lengthStick.position() == INT_BYTE_LENGTH) { break; } } if(this.lengthStick.position() == INT_BYTE_LENGTH) { this.lengthStick.flip(); length = this.lengthStick.getInt(); this.lengthStick.compact(); } else { // 消息长度读取不完整跳出 break; } } else { // 握手消息长度 length = PeerConfig.HANDSHAKE_LENGTH; } // 心跳消息:如果还有消息内容继续处理,否者跳出循环。 if(length <= 0) { this.peerSubMessageHandler.keepAlive(); if(buffer.hasRemaining()) { continue; } else { break; } } else if(length >= SystemConfig.MAX_NET_BUFFER_LENGTH || length < 0) { throw new PacketSizeException(length); } this.buffer = ByteBuffer.allocate(length); } else { // 上次消息没有读取完成,计算剩余消息数据长度。 length = this.buffer.capacity() - this.buffer.position(); } final int remaining = buffer.remaining(); if(remaining > length) { // 包含一条完整消息:处理完成后继续读取 final byte[] bytes = new byte[length]; buffer.get(bytes); this.buffer.put(bytes); this.doNext(this.buffer, address, haveAddress); this.buffer = null; } else if(remaining == length) { // 刚好一条完整消息:处理完成后跳出循环 final byte[] bytes = new byte[length]; buffer.get(bytes); this.buffer.put(bytes); this.doNext(this.buffer, address, haveAddress); this.buffer = null; break; } else if(remaining < length) { // 不是一条完整消息:跳出循环等待后续数据 final byte[] bytes = new byte[remaining]; buffer.get(bytes); this.buffer.put(bytes); break; } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy