SocketChannel.write()写入问题

发布于 2024-11-05 20:44:36 字数 537 浏览 4 评论 0原文

这里的问题是我可以看到数据正在被写入套接字,但并不总是被发送。

这是一个代码片段,

ByteBuffer writeBuffer = ByteBuffer.allocate(8192);
writeBuffer.clear();
writeBuffer.put("heartbeat".getBytes());


writeBuffer.flip();
LOG.debug("is connected: " + socketChannel.isConnected());
int bytesWritten = 0;
if (key.isWritable()) {
    while (writeBuffer.hasRemaining()) {
        bytesWritten += socketChannel.write(writeBuffer);
    }
}

我使用 TCPMon 来查看实际数据是否被写入套接字 - 确实如此。

但使用 WireShark(另一种网络监控工具)我无法看到数据包通过网卡。

任何帮助将不胜感激

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 writeBuffer = ByteBuffer.allocate(8192);
writeBuffer.clear();
writeBuffer.put("heartbeat".getBytes());


writeBuffer.flip();
LOG.debug("is connected: " + socketChannel.isConnected());
int bytesWritten = 0;
if (key.isWritable()) {
    while (writeBuffer.hasRemaining()) {
        bytesWritten += socketChannel.write(writeBuffer);
    }
}

I use TCPMon to see if the actual data gets written out to the socket - WHICH it does.

But using WireShark (another network monitoring tool) I cannot see the packet going through the NIC.

Any help would be appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

唐婉 2024-11-12 20:44:36

无论如何你的代码都是错误的。如果写入返回零,则套接字发送缓冲区已满,因此您应该注册 OP_WRITE 并返回到选择循环,而不是浪费时间旋转直到再次有空间。您目前的技术会导致其他服务通道匮乏并浪费 CPU 周期。

另外,此时测试 isConnected() 是徒劳的。这是。你连接了它。该方法告诉您有关套接字的状态,而不是连接的状态。

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.

不及他 2024-11-12 20:44:36

尝试如下

/**
 * @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();
    }
}

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文