SocketChannel의 read 메쏘드는 timeout이 존재하지 않습니다.
혹, SocketChannel 객체의 .socket() 메쏘드로 소켓객체의 타임아웃을 세팅해도 먹지 않죠.. ^^;;
그래서, non-blocking의 read 메쏘드에 대한 timeout은 busy waiting하는 형태로 타임아웃을 줄 수 있겠습니다..
// 20초
long timeout = 20 * 1000;
long stime = new Date().getTime();
long rtime = 0L;
int rvalue =0;
int rvalues = 0;
while (rtime < timeout ) {
rtime = System.currentTimeMillis() - stime;
rvalue = channel.read(rbuffer);
if(rvalue == -1)
throw new Exception("connection closed");
non-blocking SocketChannel에서 끝까지 읽어오는 코드입니다.
개인적으로 헤더 8byte, 헤더의 앞의 4byte를 전체 패킷을 길이로 잡습니다.
그리고, 아래처럼 SocketChannel에서 packet handling variables와 같이 패킷을 끝까지 다 읽어 들입니다.
아래 내용은 non-block으로 대용량의 바이너리 데이타를 읽어들이기 위해서 꼭 필요한 내용일 듯 합니다.
* read() 내용
//// packet handling variables
private int fullsize = 0;
private int readedsize =0;
private int minsize = 8;
@Override
public void read() {
try {
// 읽기
int rbytes = this.channel.read(rbuffer);
/**
* Utility class to get and put unsigned values to a ByteBuffer object.
* All methods here are static and take a ByteBuffer object argument.
* Since java does not provide unsigned primitive types, each unsigned
* value read from the buffer is promoted up to the next bigger primitive
* data type. getUnsignedByte() returns a short, getUnsignedShort() returns
* an int and getUnsignedInt() returns a long. There is no getUnsignedLong()
* since there is no primitive type to hold the value returned. If needed,
* methods returning BigInteger could be implemented.
* Likewise, the put methods take a value larger than the type they will
* be assigning. putUnsignedByte takes a short argument, etc.
*
* @author Ron Hitchens (ron@ronsoft.com)
* @version $Id: Unsigned.java,v 1.1 2002/02/12 22:06:44 ron Exp $
*/
public class Unsigned {
public static short getUnsignedByte (ByteBuffer bb){
return ((short)(bb.get() & 0xff));
}
public static void putUnsignedByte (ByteBuffer bb, int value){
bb.put ((byte)(value & 0xff));
}
public static short getUnsignedByte (ByteBuffer bb, int position){
return ((short)(bb.get (position) & (short)0xff));
}
public static void putUnsignedByte (ByteBuffer bb, int position,int value){
bb.put (position, (byte)(value & 0xff));
}