넌 블러킹(non-blocking) 소켓채널(SocketChannel)에서 끝까지 읽어오기..

넌 블러킹(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);

            // 연결종료
            if (rbytes == -1) {
                ((ChannelListener)this.listener).disconnected(this);
                this.close();
                return;
            }

            // 버퍼에 내용이 없는 경우
            if (rbytes == 0) {
                this.channel.configureBlocking(false);
                this.handle();
                return;
            } 

            // 읽은 바이트 갯수를 증감시킨다. 
            readedsize += rbytes;    
            rbufferList.add(this.copy(this.rbuffer, rbytes));

            // 최소 패킷의 길이에서 패킷을 전체 길이를 리턴한다. 
            if(readedsize >= minsize && this.fullsize == 0) {
                this.fullsize = this.createResultBuffer().getInt();
                for(int i=0; i< this.rbufferList.size(); i++) {
                    this.rbufferList.get(i).position(0);
                }
            }

            // 패킷을 다 읽어 들였다. 
            if(fullsize == readedsize) {
                ((ChannelListener)this.listener).arrived(this,this.createResultBuffer());
            }

            this.channel.configureBlocking(false);
            this.handle();
        } catch(Exception e) { // disconnected
            try {
                this.close();
            } catch(IOException ie) {
                new CallbackExceptionHandler().handle(ie);
            }

            ((ChannelListener)this.listener).disconnected(this);
        }
    }

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.