jpd*_*gle 4 java sockets network-programming nio
在Windows上使用Sun Java VM 1.5或1.6,我连接一个非阻塞套接字.然后我填写一条ByteBuffer消息输出,并尝试进入write()SocketChannel.
如果要写入的数量大于套接字TCP输出缓冲区中的空间量,我希望写入只能部分完成(这是我所期望的直观,这也是我对文档的理解),但那不是什么发生.该write() 总似乎返回报告写全款,即使是几兆字节(套接字的SO_SNDBUF为8KB,多少,比我的多兆字节输出消息少得多).
这里的问题是我无法测试处理部分写入输出的情况的代码(注册WRITE选择器的兴趣集并执行select()等待直到写入其余部分),因为这种情况似乎永远不会发生.我不明白的是什么?
我设法重现了一个可能类似于你的情况.我认为,具有讽刺意味的是,您的收件人比您编写数据的速度更快.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您运行上述服务器,然后让上面的客户端尝试写入10个128 kB的数据块,您将看到每个写操作都会写入整个缓冲区而不会阻塞.但是,如果您修改上述服务器而不是从连接中读取任何内容,您将看到只有客户端上的第一个写操作将写入128 kB,而所有后续写入将返回0.
服务器从连接读取时的输出:
to write: 131072, written: 131072
to write: 131072, written: 131072
to write: 131072, written: 131072
...
Run Code Online (Sandbox Code Playgroud)
服务器未从连接读取时的输出:
to write: 131072, written: 131072
to write: 131072, written: 0
to write: 131072, written: 0
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2862 次 |
| 最近记录: |