80 年代屌丝男买了一个 BP 机用来追妹,男士使用传呼台给女生留言:
男:下午一起看个电影?[早晨 10 点]
这是男生唯一心动的女生,所以一直守着自己的 BP 机,等待女生回复,就这样一天过去了,直到:
男:BP 没电,自动关机。
80 年代的公子哥买了一个大哥大,关键是这个公子哥太花心,同时中意了两个妹子,于是他就开始了把妹过程。 公子哥用大哥大给女 A 打电话:
公子哥 -> 女 A:下午一起看个电影?[早晨 10 点] 女 A -> 公子哥:我正在吃饭,你晚点再打过来?
公子哥用大哥大给女 B 打电话:
公子哥 -> 女 B:下午一起看个电影?[早晨 10 点 1 分] 女 B -> 公子哥:我正在吃饭,你晚点再打过来?
过了 10 分钟公子哥再次打电话询问
公子哥 -> 女 A:怎么样,有空吗?[早晨 10 点 10 分] 女 A -> 公子哥:我下午陪爸爸打马球,不去了。 公子哥 -> 女 B:怎么样,有空吗?[早晨 10 点 11 分] 女 B -> 公子哥:好呀,下午 3 点来我家接我吧。 公子哥 -> 女 B:好嘞,我开车去接你。
最终公子哥成功了追求到了女 B,这个故事告诉我们,成功的前提是有钱。(你怎么看?)
21 世纪初期,还没有智能机,不过诺基亚 1110 砸核桃神机已经普及了,下面就是新时代大学生小王用自己的诺基亚 1110 的把妹过程。 小王给中意的两个女生直接发短信留言(群发):
小王 -> 女 A:下午一起看个电影?[早晨 10 点] 小王 -> 女 B:下午一起看个电影?[早晨 10 点]
发完短信小王去看《西游记》去了。10分钟以后电话响起,收到了妹子的短信,小王拿起了手机阅读了消息并进行回复。
女 B -> 小王:好呀,下午 3 点来我家接我吧 [早晨 10 点 10 分] 小王 -> 女 B:好的,我去接你不见不散。
AIO 包括了 NIO 的所有优缺点的同时,增加了异步回调的能力,由此解决的问题是不需要同步的等待非阻塞 IO 的反馈,所以 NIO 叫做异步非阻塞 IO 模型。
说了这么多,用 NIO 实现一个把妹聊天程序呗?
public class NioServer {
public void start() throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(6789));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务器启动成功");
while (true) {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isAcceptable()) {
iterator.remove();
handleAccept(serverSocketChannel, selector);
} else if (selectionKey.isReadable()) {
handleRead(selectionKey);
} else {
System.out.println("其他请求");
}
}
}
}
private void handleRead(SelectionKey selectionKey) throws IOException {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
StringBuilder request = new StringBuilder();
while (socketChannel.read(byteBuffer) > 0) {
byteBuffer.flip();
request.append(StandardCharsets.UTF_8.decode(byteBuffer));
}
if (request.length() > 0) {
System.out.println("服务端收到消息:" + request.toString());
}
}
private void handleAccept(ServerSocketChannel serverSocketChannel, Selector selector) throws IOException {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("有新人进入聊天室");
socketChannel.write(StandardCharsets.UTF_8.encode("进入聊天室,现在可以聊天了"));
}
public static void main(String[] args) throws IOException {
new NioServer().start();
}
}
public class NioClient {
public void start() throws IOException {
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(6789));
Selector selector = Selector.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
new Thread(new NioClientHandler(selector)).start();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String request = scanner.nextLine();
if (request != null && request.length() > 0) {
socketChannel.write(StandardCharsets.UTF_8.encode(request));
}
}
}
public static void main(String[] args) throws IOException {
new NioClient().start();
}
private class NioClientHandler implements Runnable {
private Selector selector;
public NioClientHandler(Selector selector) {
this.selector = selector;
}
@Override
public void run() {
try {
while (true) {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = (SelectionKey) iterator.next();
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
StringBuilder response = new StringBuilder();
while (socketChannel.read(byteBuffer) > 0) {
byteBuffer.flip();
response.append(StandardCharsets.UTF_8.decode(byteBuffer));
}
if (response.length() > 0) {
System.out.println("接收服务端消息:" + response);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
推荐文章面试官问:前后端分离项目,有什么优缺点?我说:没
2020 年腾讯新增 20 亿行代码,鹅厂第一编程语言还是它
通俗讲解分布式锁,看完不懂算我输
写博客能月入10K?
一款基于 Spring Boot 的现代化社区(论坛/问答/社交网络/博客)更多项目源码
这或许是最美的Vue+Element开源后台管理UI推荐一款高颜值的 Spring Boot 快速开发框架
一款基于 Spring Boot 的现代化社区(论坛/问答/社交网络/博客)
13K点赞都基于 Vue+Spring 前后端分离管理系统ELAdmin,大爱想接私活时薪再翻一倍,建议根据这几个开源的SpringBoot项目