boolean send() throws IOException {
        if (this.closed) {
            this.failAllRequests();
            throw new SocketClosedException();
        }

        while (!this.writeRequests.isEmpty()) {
            //SocketSendData data = this.sendQueue.peek();
            WriteRequest writeRequest = this.writeRequests.peek();

            ByteBuffer buffer = writeRequest.bufferProvider.get();

            if (buffer == null) {
                // if IBufferProvider returns null, it means, that user don't want send packet.
                writeRequest.listener.onCancelled();

                this.writeRequests.poll();
                continue;
            }

            int writed;

            try {
                writed = this.channel.write(buffer);
            } catch (IOException ex) {
                this.failAllRequests();
                throw ex;
            }

            if (writed == -1) {
                this.failAllRequests();
                throw new SocketClosedException();
            }

            if (!buffer.hasRemaining()) {
                this.writeRequests.poll();

                writeRequest.listener.onSent();
            }

            if (writed == 0) break;
        }

        return this.writeRequests.isEmpty();
    }