当前位置:网站首页>网络通信编程基础,BIO,NIO
网络通信编程基础,BIO,NIO
2022-07-29 20:53:00 【yfyh2021】
编程中的Socket是什么?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,其实就是一个门面模式。
BIO的阻塞提现在两个方面
- 若一个服务器启动就绪,那么服务器的主线程就一直等待着客户端连接,这个等待过程中主线程就在阻塞。
public class ServerSingle { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(8888)); System.out.println("Start Server ...."); int connectCount = 0; try { while (true){ Socket socket = serverSocket.accept(); System.out.println("accept client socket ....total =" + ( ++connectCount)); ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream()); ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); String userName = inputStream.readUTF(); System.out.println("Accept client message:"+userName); outputStream.writeUTF("Hello,"+userName); outputStream.flush(); } }catch (Exception e){ e.printStackTrace(); }finally { serverSocket.close(); } } }
可以看到主线程启动,线程阻塞在了accept()监听方法,后面的没有打印
- 在连接建立之后,在读到socket信息之前,线程也是一直在等待的,阻塞在那里。
public class Client { public static void main(String[] args) throws IOException { Socket socket = null; ObjectOutputStream output = null; ObjectInputStream input = null; InetSocketAddress addr = new InetSocketAddress("127.0.0.1",8888); try { socket = new Socket(); socket.connect(addr); System.out.println("Connect Server success!!"); output = new ObjectOutputStream(socket.getOutputStream()); input = new ObjectInputStream(socket.getInputStream()); System.out.println("Ready send message....."); output.writeUTF("yang"); output.flush(); System.out.println(input.readUTF()); } catch (IOException e) { e.printStackTrace(); }finally { if (socket!=null) socket.close(); if (output!=null) output.close(); if (input!=null) input.close(); } } }
我们在client中打上断点,debug启动。可以看到client连接成功,server端的accept也接收到了,但是主线程又阻塞在了等待socket的输出当中
NIO和BIO的主要区别
- NIO和IO的主要区别是IO是面向流的,而NIO是面向缓冲区的。
- 阻塞与非阻塞
NIO三大核心组件
- Selector。记录发生的事件,以及服务端和客户端关注的事件。
- channel。本质上就是socket的包装类。分为serverSocketChannel和socketChannel,serverSocketChannel只关心accept的事件,也只有服务端才会关心;而socketChannel就是普通的socket关心读写事件。客户端的socketChannel关心connect事件。
- buffer。缓冲区,我们上面说到NIO是面向缓冲区的,就是这个buffer,就是因为buffer的存在,使得线程不需要等待。
重要概念:SelectionKey
SelectionKey是一个抽象类,表示selectableChannel在Selector中注册的标识,其中有四种状态分别是OP_READ(读事件),OP_WRITE(写事件),OP_CONNECT(发起连接事件),OP_ACCEPT(接收连接事件)
直接内存比堆内存快在哪
jvm在向socket缓冲区发送信息时,会在堆外重新开辟一块内存,将要发送的信息拷贝进去。这样做的原因是防止在gc的时候,改变堆内信息的位置。
堆外内存的优点和缺点
堆外内存相比于堆内内存有几个优势:
1 减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作(可能使用多线程或者时间片的方式,根本感觉不到)
2 加快了复制的速度。因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。
而福之祸所依,自然也有不好的一面:
1 堆外内存难以控制,如果内存泄漏,那么很难排查
2 堆外内存相对来说,不适合存储很复杂的对象。一般简单的对象或者扁平化的比较适合。
边栏推荐
猜你喜欢
随机推荐
7 行代码搞崩溃 B 站,原因令人唏嘘!
In 2022, you still can't "low code"?Data science can also play with Low-Code!
PyQt5学习一(环境搭建)
阿里 P8 爆出的这份大厂面试指南,看完工资暴涨 30k!
博世集团启动量子数字孪生计划
02-SDRAM:自动刷新
C#笔记 之 Oracle.ManagedDataAccess包的安装及配置
《张卫国的夏天》欢乐来袭,黄磊、刘奕君携手演绎“冤种”兄弟
336. Palindromic Pairs
SAP ABAP OData 服务 Data Provider Class 的 GET_ENTITYSET 方法实现指南试读版
Huawei laptop keyboard locked (how does the laptop keyboard light up)
赶紧进来!!!带你认识C语言基本数据类型
容器网络硬核技术内幕 (小结-中)
Fully automated machine learning modeling!The effect hangs the primary alchemist!
Break the rules!MongoDB introduces SQL?
全自动化机器学习建模!效果吊打初级炼丹师!
针对自动识别大麦网滑块验证码,提出解决方案,并进行分析、总结
太卷了,企业级的智慧物业系统,也完全开源....
第3章业务功能开发(线索关联市场活动,动态搜索)
leetcode-593:有效的正方形