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

io.github.icodegarden.commons.nio.java.SocketChannelSpace Maven / Gradle / Ivy

The newest version!
package io.github.icodegarden.commons.nio.java;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.github.icodegarden.commons.nio.Codec;
import io.github.icodegarden.commons.nio.ExchangeMessage;

/**
 * NOT THREAD SAFE
* 每个对应的连接都需要一个空间,无论client、serverSideClient * @author Fangfang.Xu * */ class SocketChannelSpace { private static final Logger log = LoggerFactory.getLogger(SocketChannelSpace.class); private final String name; private final ByteBuffer headerBuffer = ByteBuffer.allocate(Codec.HEADER); private ByteBuffer bodyBuffer; public SocketChannelSpace(String name) { this.name = name; } public void write(SocketChannel socketChannel, ExchangeMessage message) throws IOException { ByteBuffer buffer = Codec.encode(message); write(socketChannel, buffer); } private void write(SocketChannel socketChannel, ByteBuffer buffer) throws IOException { buffer.flip();// 必须,flip后才能读 /** * channel的写操作在并发时,必须保证顺序写入,否则字节错乱 */ synchronized (this) { while (buffer.hasRemaining()) { socketChannel.write(buffer); } } } /** * @return Null if not full */ public ExchangeMessage read(SocketChannel channel) throws IOException { if (bodyBuffer == null) { if (log.isDebugEnabled()) { log.debug("{} reading header...,channel:{}",channel); } channel.read(headerBuffer); if (headerBuffer.position() == 0) {// 当client close时,server 会收到read,但读不到数据 throw new ClosedChannelException();// 意味着client close了 } // read header if (headerBuffer.position() < Codec.HEADER) { if (log.isDebugEnabled()) { log.debug("{} position not at header length, continue reading...",name); } return null; } // headerBuffer.flip();get指定index不用flip int bodyLength = headerBuffer.getInt(12); bodyBuffer = ByteBuffer.allocate(bodyLength); return null; } else { channel.read(bodyBuffer); // buffer.position(headerBuffer.limit());//使用put position不会自动加 if (bodyBuffer.position() < bodyBuffer.limit()) { if (log.isDebugEnabled()) { log.debug("{} position not reach body length, continue read...", name); } return null; } ExchangeMessage message = Codec.decode(headerBuffer, bodyBuffer); headerBuffer.clear(); bodyBuffer = null; return message; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy