当前位置:  开发笔记 > 编程语言 > 正文

为什么即使在非阻塞套接字上,SocketChannel写入也总是完整的?

如何解决《为什么即使在非阻塞套接字上,SocketChannel写入也总是完整的?》经验,为你挑选了1个好方法。

在Windows上使用Sun Java VM 1.5或1.6,我连接一个非阻塞套接字.然后我填写一条ByteBuffer消息输出,并尝试进入write()SocketChannel.

如果要写入的数量大于套接字TCP输出缓冲区中的空间量,我希望写入只能部分完成(这是我所期望的直观,这也是我对文档的理解),但那不是什么发生.该write() 似乎返回报告写全款,即使是几兆字节(套接字的SO_SNDBUF为8KB,多少,比我的多兆字节输出消息少得多).

这里的问题是我无法测试处理部分写入输出的情况的代码(注册WRITE选择器的兴趣集并执行select()等待直到写入其余部分),因为这种情况似乎永远不会发生.我不明白的是什么?



1> Alexander..:

我设法重现了一个可能类似于你的情况.我认为,具有讽刺意味的是,您的收件人比您编写数据的速度更快.

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
  public static void main(String[] args) throws Exception {
    final ServerSocket ss = new ServerSocket(12345);
    final Socket cs = ss.accept();
    System.out.println("Accepted connection");

    final InputStream in = cs.getInputStream();
    final byte[] tmp = new byte[64 * 1024];
    while (in.read(tmp) != -1);

    Thread.sleep(100000);
  }
}



import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class MyNioClient {
  public static void main(String[] args) throws Exception {
    final SocketChannel s = SocketChannel.open();
    s.configureBlocking(false);
    s.connect(new InetSocketAddress("localhost", 12345));
    s.finishConnect();

    final ByteBuffer buf = ByteBuffer.allocate(128 * 1024);
    for (int i = 0; i < 10; i++) {
      System.out.println("to write: " + buf.remaining() + ", written: " + s.write(buf));
      buf.position(0);
    }
    Thread.sleep(100000);
  }
}

如果您运行上述服务器,然后让上面的客户端尝试写入10个128 kB的数据块,您将看到每个写操作都会写入整个缓冲区而不会阻塞.但是,如果您修改上述服务器而不是从连接中读取任何内容,您将看到只有客户端上的第一个写操作将写入128 kB,而所有后续写入将返回0.

服务器从连接读取时的输出:

to write: 131072, written:  131072
to write: 131072, written:  131072
to write: 131072, written:  131072
...

服务器未从连接读取时的输出:

to write: 131072, written:  131072
to write: 131072, written:  0
to write: 131072, written:  0
...  

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有