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 还在正常工作吗,假设现在把服务端加点代码:读出所有数据新建那个图片后,再向客户端发送数据,是不是就不能成功了。 1
tairan2006 2020-03-15 11:03:07 +08:00 via Android
哥们你应该先了解 socket 通信的基本知识再看代码
|
2
Chinsung 2020-03-17 18:40:05 +08:00
nio,还是 java,首先得 select 搞搞,看看具体的 key,你才能明白大概是个什么原理。
建议找几个有图的看,然后自己照着例子试试 api。 nio 主要解决的是从底层开始搞定用低线程数处理大量连接的问题(相比较同步 IO ),可以了解下 linux 的 epoll,select。 |