繁体   English   中英

SocketChannel write()返回,没有错误,但实际上没有发送任何数据

[英]SocketChannel write( ) returns with no error but no data was actually sent

我正在使用SocketChannel与远程服务器通信。 我使用socketChannel.write()发送数据,没有错误和异常,但是服务器日志指示未接收到任何数据。 客户端tcp流量监视器还显示未发送ByteBuffer中的字符串消息。

谁能给我一个提示,为什么会这样呢? 谢谢!

public class Client implements Runnable {
    SocketChannel socketChannel;
    Selector selector;
    SelectionKey key;
    ByteBuffer inbuf, outbuf;
    int id;
    @Override
    public void run() {
    try {
        // prepare inbuf and outbuf
        inbuf = ByteBuffer.allocate(10000);
        outbuf = ByteBuffer.allocate(10000);

        // prepare a socket channel for communication
        socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("<remote server ip>", ));
        selector = Selector.open();
        socketChannel.configureBlocking(false);
        key = socketChannel.register(selector, SelectionKey.OP_READ
                | SelectionKey.OP_WRITE);

        while (selector.select() > 0) {

            if (key.isReadable()) {
                // read from channel when server sends data
                read();
            }

            if (key.isWritable()) {
                // write
                Random r = new Random(500);
                write("b", r.nextInt(), r.nextInt());
                for (int i = 0; i < 10; i++) {
                    // write a message to server after 1 second
                    Thread.sleep(1000);
                    write("m", r.nextInt(), r.nextInt());
                }
                write("e", r.nextInt(), r.nextInt());
            }
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

private void write(String action, int x, int y) throws IOException {
    String msg = String.format("%s:%d:%d:%d", action, id, x, y);
    int r=outbuf.remaining();

    outbuf.put(msg.getBytes());
    int rBytes = outbuf.remaining();
    boolean connected = socketChannel.isConnected();
    Socket sock = socketChannel.socket();

    if (connected && sock.isConnected() && !sock.isOutputShutdown())
>>>>>>>>>>    socketChannel.write(outbuf);
    else
        System.out.println("Connection broken!");

    System.out.printf("Client %d told server:%s\n", id, msg);
    //outbuf.clear();
}

   ... //read omitted here

将内容放入缓冲区或读取内容后,您必须翻转缓冲区以写入或从中获取数据。 检查Buffer类中的flip()方法。 医生说

翻转此缓冲区。 将限制设置为当前位置,然后将该位置设置为零。 如果定义了标记,则将其丢弃。 在执行一系列通道读取或放置操作之后,调用此方法以准备一系列通道写入或相对get操作。

所以在put之后添加buffer.flip()应该可以解决问题:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM