void receive() throws IOException {
        if (this.closed) throw new SocketClosedException();

        class Container {
            public IOException exception = null;
            public boolean isClosed = false;
        }

        final Container container = new Container();

        this.listener.onData(new IBufferReadable() {
            @Override
            public int read(ByteBuffer buffer) {
                int readed;

                try {
                    readed = TCPSocket.this.channel.read(buffer);
                } catch (IOException ex) {
                    container.exception = ex;
                    return 0;
                }

                if (readed != -1) {
                    return readed;
                } else {
                    container.isClosed = true;
                    return 0;
                }
            }
        });

        if (container.exception != null) {
            throw container.exception;
        }

        if (container.isClosed) {
            throw new SocketClosedException();
        }
    }