当前位置:网站首页>网络通信编程基础,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 堆外内存相对来说,不适合存储很复杂的对象。一般简单的对象或者扁平化的比较适合。
边栏推荐
猜你喜欢

微信小程序 30 自定义模板和获取用户登录凭证

4. SAP ABAP OData 服务 Data Provider Class 的 GET_ENTITYSET 方法实现指南

The Ministry of Human Resources and Social Security announced that "database operation administrator" has become a new occupation, and OceanBase participated in the formulation of occupational standar

PyQt5学习一(环境搭建)

VR直播营销需求增加,数据模块为我们铺路

APM电机输出逻辑(Motors类详解)

太卷了,企业级的智慧物业系统,也完全开源....

探索创客教育在线管理实施体系

南信大提出TIPCB,一个简单但有效的用于基于文本的人员搜索的基于部分的卷积baseline

高通WLAN框架学习(31)-- Power save
随机推荐
关于云计算的海量数据存储模型[通俗易懂]
根据昵称首字母生成头像
Cobaltstrike and BurpSuite desktop shortcut configuration
刚重装的win7系统不能上网(深度系统安装步骤)
【数据库】mysql日期格式转换
ALBERT: A Lite BERT for Self-supervised Learning of Language Representations
【Nacos】nacos1.x 单机、内置数据库模式修改密码
网安学习-内网渗透2
Liu Genghong, boys and girls, come here!Sports data analysis and mining!(with a full set of code and data sets)
五个供应商销售谈判策略的识别以及应对它们的方法
断言+异常处理类,代码更简洁了
Dry goods!Cooperative Balance in Federated Learning
WeChat Mini Program 30 Customizing Templates and Obtaining User Login Credentials
QT安装、创建项目与调试,在VS中的使用:手把手教程
人社部公布“数据库运行管理员”成新职业,OceanBase参与制定职业标准
容器网络硬核技术内幕 (小结-中)
MySQL - 设计游戏用户信息表
如何优雅的自定义 ThreadPoolExecutor 线程池
APM电机输出逻辑(Motors类详解)
[Database] mysql date format conversion