package org.kne.cloud.network.srv6; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import org.kne.cloud.network.NetworkPacket; public abstract class KLALBRoutingProtocolPacket extends NetworkPacket { public static final int RINFO_REQ=0; public static final int RINFO=1; public static final int JSON_DATA=2; private static final int HEADER_CAPACITY = 32; //public static final ByteArrayPool dataarraypool=new ByteArrayPool(5000, 8192); protected volatile ByteBuffer header; protected KLALBRoutingProtocolPacket(ByteBuffer header) { super(); this.header = header; } public KLALBRoutingProtocolPacket(int type) { super(); header=NetworkPacket.bufferAllocator.allocate(40); header.put((byte) type); } @Override public String toString() { return "KLALBRoutingProtocolPacket [type=" + getType() + "]"; } public int getType() { return header.get(0)&0xff; } private long sndtime,rcvtime; public void writeToChannel(WritableByteChannel dto) throws IOException { sndtime=System.nanoTime(); dto.write(header.slice(0, (int) getHeaderSize())); } @Override protected boolean needEndPosition() { return false; } public void readFromChannel(ReadableByteChannel din,long length) throws IOException { rcvtime=System.nanoTime(); //System.out.println(this+" "+getHeaderSize()); header.limit((int) getHeaderSize()); while(header.hasRemaining()){ if(din.read(header)==-1) { throw new EOFException(); } } } protected long getHeaderSize() { return 1; } public long getSndtime() { return sndtime; } public long getRcvtime() { return rcvtime; } public long getTotalLength() { return getHeaderSize(); } protected ByteBuffer getHeader() { return header; } public static KLALBRoutingProtocolPacket readKLALBPacketFromStream(DataInputStream in) throws IOException { return readKLALBPacketFromChannel(Channels.newChannel(in)); } public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in) throws IOException { return readKLALBPacketFromChannel(in, -1); } public static KLALBRoutingProtocolPacket readKLALBPacketFromChannel(ReadableByteChannel in, long packetLength) throws IOException { while(true) { ByteBuffer bb=NetworkPacket.bufferAllocator.allocate(40); bb.limit(1); while(bb.hasRemaining()){ if(in.read(bb)==-1) { return null; } } int type=bb.get(0); bb.limit(bb.capacity()); KLALBRoutingProtocolPacket klp; switch(type) { case RINFO_REQ: klp=new RouterInfoRequestPacket(bb); if(packetLength < 0) klp.readFromChannel(in); else klp.readFromChannel(in, packetLength); return klp; case RINFO: klp=new RouterInfoPacket(bb); if(packetLength < 0) klp.readFromChannel(in); else klp.readFromChannel(in, packetLength); return klp; case JSON_DATA: klp=new JsonDataPacket(bb); klp.readFromChannel(in); return klp; } //throw new StreamCorruptedException("unknown package type:"+type); System.err.println("ignore unknown KLALBRoutingProtocolPacket type:"+type); } } public static void writeKLALBPacketToStream(DataOutputStream out,KLALBRoutingProtocolPacket klb) throws IOException { writeKLALBPacketToChannel(Channels.newChannel(out),klb); } public static void writeKLALBPacketToChannel(WritableByteChannel writableByteChannel,KLALBRoutingProtocolPacket klb) throws IOException { klb.writeToChannel(writableByteChannel); } }