package TestNIO;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class BlockingClient {
public static void main(String[] args) throws IOException {
SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
ByteBuffer buf = ByteBuffer.allocate(1024);
while (inChannel.read(buf) != -1) {
buf.flip();
sChannel.write(buf);
buf.clear();
}
//sChannel.shutdownOutput();
//inChannel.close();
sChannel.close();
while (true) {
System.out.println("死循环");
}
}
}
package TestNIO;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class BlockingServer {
public static void main(String[] args) throws IOException {
ServerSocketChannel ssChannel = ServerSocketChannel.open();
ssChannel.bind(new InetSocketAddress(9898));
FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"),
StandardOpenOption.WRITE, StandardOpenOption.CREATE);
SocketChannel sChannel = ssChannel.accept();
System.out.println("BlockingServer accept");
ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println("BlockingServer accept1");
int i = 2;
while (sChannel.read(buf) != -1) {
System.out.println("BlockingServer accept"+i++);
buf.flip();
outChannel.write(buf);
buf.clear();
}
System.out.println("already get data, and output to local file");
sChannel.close();
outChannel.close();
ssChannel.close();
}
}
如上,是两个最简单的例子。经过几次 debug,有以下理解(也不知道对不对):
SocketChannel sChannel = ssChannel.accept()
这里。SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
以后,服务端不阻塞在SocketChannel sChannel = ssChannel.accept()
这里,继续往下执行。(sChannel.read(buf)
会阻塞在这里,直到客户端执行了一次sChannel.write(buf)
后,服务端才会继续往下执行,经过循环,在下一次的(sChannel.read(buf)
阻塞。sChannel.shutdownOutput()
或者sChannel.close()
后,服务端不会继续在(sChannel.read(buf)
阻塞,而此时返回值为-1,所以退出循环sChannel.close()
,服务端那边的 SocketChannel 还在正常工作吗,假设现在把服务端加点代码:读出所有数据新建那个图片后,再向客户端发送数据,是不是就不能成功了。这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.