简体   繁体   English

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

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

I am using SocketChannel to communicate with remote server. 我正在使用SocketChannel与远程服务器通信。 I send data using socketChannel.write() with no errors and exceptions, however, the server log indicates no data was received; 我使用socketChannel.write()发送数据,没有错误和异常,但是服务器日志指示未接收到任何数据。 client tcp traffic monitor also shows that the string message in the ByteBuffer was not sent. 客户端tcp流量监视器还显示未发送ByteBuffer中的字符串消息。

Could anyone give me a hint why this is the case? 谁能给我一个提示,为什么会这样呢? Thank you! 谢谢!

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

After putting stuff into a Buffer, or reading stuff into it you have to flip the buffer to write or get the data from it. 将内容放入缓冲区或读取内容后,您必须翻转缓冲区以写入或从中获取数据。 Check the flip() method in the Buffer class. 检查Buffer类中的flip()方法。 The docs say 医生说

Flips this buffer. 翻转此缓冲区。 The limit is set to the current position and then the position is set to zero. 将限制设置为当前位置,然后将该位置设置为零。 If the mark is defined then it is discarded. 如果定义了标记,则将其丢弃。 After a sequence of channel-read or put operations, invoke this method to prepare for a sequence of channel-write or relative get operations. 在执行一系列通道读取或放置操作之后,调用此方法以准备一系列通道写入或相对get操作。

So adding a buffer.flip() after the put should do the trick :) 所以在put之后添加buffer.flip()应该可以解决问题:)

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

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