package com.forest.ape.nio; import java.io.IOException; import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.forest.ape.server.ApeServer; import com.forest.ape.server.Server; public class NettyServerCnxn extends ServerCnxn { Logger LOG = LoggerFactory.getLogger(NettyServerCnxn.class); Channel channel; Server server; NettyServerCnxnFactory nettyServerCnxnFactory; long sessionId; public long getSessionId() { return sessionId; } public void setSessionId(long sessionId) { this.sessionId = sessionId; } public NettyServerCnxn(Channel channel, Server s, NettyServerCnxnFactory nettyServerCnxnFactory) { this.channel = channel; this.nettyServerCnxnFactory = nettyServerCnxnFactory; this.server = s; } ByteBuffer bb = null; int Default_Size = 100; int INT_SIZE = 4; int readIndex = 0; boolean isReadingLen = false; public void receiveMessage(ChannelBuffer channelBuffer) throws IOException { LOG.debug("process message..., buffer length:" + channelBuffer.readableBytes()); try { while (channelBuffer.readable()) { if (bb != null) { bb.limit(bb.capacity()); if (bb.remaining() <= channelBuffer.readableBytes()) { // LOG.debug("read byte len:" + (bb.limit() - bb.position()) + ", postion:" + bb.position() + ", limit:" + bb.limit()); LOG.debug("read index:" + readIndex + ", read len:" + bb.remaining()); readIndex += bb.remaining(); channelBuffer.readBytes(bb); if (isReadingLen == false) { server.processPacket(this, bb); bb = null; increasePacketReceived(); } else { bb.position(0); int dataLen = bb.getInt(); if (dataLen > 1024) throw new IOException("data length: " +dataLen+ "is too long!!"); isReadingLen = false; LOG.debug("allocate length:" + dataLen); bb = ByteBuffer.allocate(dataLen); // ByteBuffer dup = bb.duplicate(); // dup.flip(); // LOG.trace("queuedBuffer 0x" // + ChannelBuffers.hexDump(ChannelBuffers.copiedBuffer(dup))); } } else { int len = channelBuffer.readableBytes(); bb.limit(bb.position() + len); LOG.debug("read index:" + readIndex + ", read len:" + len); readIndex += len; channelBuffer.readBytes(bb); } } else { // int len = channelBuffer.readInt(); // if (len < 4) { // throw new IOException("recv len:" + len); // } // LOG.debug("allocate length:" + len); bb = ByteBuffer.allocate(INT_SIZE); if (channelBuffer.readableBytes() >= INT_SIZE) { // int dataLen = channelBuffer.readInt(); LOG.debug("read index:" + readIndex + ", read len:" + dataLen); readIndex += dataLen; if (dataLen > 1024) throw new IOException("data length: " +dataLen+ " is too long!!"); bb = ByteBuffer.allocate(dataLen); isReadingLen = false; } else { bb.limit(channelBuffer.readableBytes()); LOG.debug("read index:" + readIndex + ", read len:" + channelBuffer.readableBytes()); readIndex += channelBuffer.readableBytes(); channelBuffer.readBytes(bb); isReadingLen = true; } } } } catch (Exception e) { LOG.error(e.getMessage(), e); channel.close(); } // apeServer.processPacket(cnxn, e.getMessage()); } static AtomicLong cnt = new AtomicLong(0); private void increasePacketReceived() { // TODO Auto-generated method stub LOG.info("^_^ recv one packet! seq:" + cnt.addAndGet(1)); } public void close() { nettyServerCnxnFactory.removeCnxn(this); if (channel.isOpen()) { LOG.debug("closing channel, ox" + Long.toHexString(sessionId)); channel.close(); } } public void sendMessage(ByteBuffer buf) { } }