SocketChannel.write() writing problem

后端 未结 2 1107
旧时难觅i
旧时难觅i 2021-01-03 06:00

The issue here is I can see that the data is being written out to the socket but it is not ALWAYS being sent.

Here\'s a code sniplet

ByteBuffer write         


        
相关标签:
2条回答
  • 2021-01-03 06:22

    Your code is wrong anyway. If the write returns zero the socket send buffer is full, so you should register OP_WRITE and return to the select loop, rather than waste time spinning until there is room again. Your present technique starves the other channels of service and wastes CPU cycles.

    Also, testing isConnected() at this point is futile. It is. You connected it. That method tells you about the state of the socket, not the connection.

    0 讨论(0)
  • 2021-01-03 06:44

    Try it as follows

    /**
     * @param socketChannel
     * @param buf
     * @return no. of bytes written to the socket
     * @throws IOException
     */
    public static int writeByteBuffer(SocketChannel socketChannel, ByteBuffer buf) throws IOException {
    
        boolean blocking = socketChannel.isBlocking();
        Selector selector = Selector.open();
        int totalWritten = 0;
        try {
    
            socketChannel.configureBlocking(false);
    
            // pass SelectionKey.OP_READ | SelectionKey.OP_WRITE for read and
            // write
            socketChannel.register(selector, SelectionKey.OP_WRITE);
    
            selector.select();
    
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
    
            Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
    
            outerOfWriting: while (keyIterator.hasNext()) {
    
                SelectionKey key = keyIterator.next();
    
                boolean writable = key.isWritable();
    
                if (writable) {
    
                    SocketChannel channel = (SocketChannel) key.channel();
    
                    boolean hasRemaining = false;
                    while (hasRemaining = buf.hasRemaining()) {
                        int written = channel.write(buf);
                        totalWritten += written;
    
                        if (written == 0) {                         
                            selector.select();
                            selectedKeys = selector.selectedKeys();
                            keyIterator = selectedKeys.iterator();
                            continue outerOfWriting;
                        }
                    }
    
                    if (!hasRemaining) {
                        key.cancel();
                        break;
                    }
                }
            }
    
        } finally {
            try {
                selector.close();
                socketChannel.configureBlocking(blocking);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        return totalWritten;
    }
    
    public static void main(String[] args) {
    
        try {
            ByteBuffer writeBuffer = ByteBuffer.allocate(8192);
            writeBuffer.clear();
            writeBuffer.put("heartbeat".getBytes());
            writeBuffer.flip();
    
            SocketChannel socketChannel = null;//initialize
            writeByteBuffer(socketChannel, writeBuffer);
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    0 讨论(0)
提交回复
热议问题