当前位置:网站首页>Socket回顾与I/0模型
Socket回顾与I/0模型
2022-07-31 19:21:00 【悠然予夏】
1、Socket网络编程回顾
1.1、Socket概述
Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。
1.2、Socket整体流程
Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,可以选择任意一个当前没有被其他进程使用的端口。
客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。
1.3、代码实现
服务端代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerDemo {
public static void main(String[] args) throws Exception {
//1.创建一个线程池,如果有客户端连接就创建一个线程, 与之通信
ExecutorService executorService = Executors.newCachedThreadPool();
//2.创建 ServerSocket 对象
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务器已启动");
while (true) {
//3.监听客户端
final Socket socket = serverSocket.accept();
System.out.println("有客户端连接");
//4.开启新的线程处理
executorService.execute(new Runnable() {
@Override
public void run() {
handle(socket);
}
});
}
}
public static void handle(Socket socket) {
try {
System.out.println("线程ID:" + Thread.currentThread().getId()
+ " 线程名称:" + Thread.currentThread().getName());
//从连接中取出输入流来接收消息
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
int read = is.read(b);
System.out.println("客户端:" + new String(b, 0, read));
//连接中取出输出流并回话
OutputStream os = socket.getOutputStream();
os.write("没钱".getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭连接
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端代码
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientDemo {
public static void main(String[] args) throws Exception {
while (true) {
//1.创建 Socket 对象
Socket s = new Socket("127.0.0.1", 9999);
//2.从连接中取出输出流并发消息
OutputStream os = s.getOutputStream();
System.out.println("请输入:");
Scanner sc = new Scanner(System.in);
String msg = sc.nextLine();
os.write(msg.getBytes());
//3.从连接中取出输入流并接收回话
InputStream is = s.getInputStream();
byte[] b = new byte[1024];
int read = is.read(b);
System.out.println("老板说:" + new String(b, 0, read).trim());
//4.关闭
s.close();
}
}
}
2、I/O模型
2.1、I/O模型说明
- I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能
- Java 共支持 3 种网络编程模型/IO 模式:BIO(同步并阻塞)、NIO(同步非阻塞)、AIO(异步非阻塞)
阻塞与非阻塞
主要指的是访问IO的线程是否会阻塞(或处于等待)线程访问资源,该资源是否准备就绪的一种处理方式
同步和异步
主要是指的数据的请求方式
同步和异步是指访问数据的一种机制
2.2、BIO(同步并阻塞)
Java BIO就是传统的 socket编程.
BIO(blocking I/O) : 同步阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器)。
工作机制
BIO问题分析
- 每个请求都需要创建独立的线程,与对应的客户端进行数据 Read,业务处理,数据 Write
- 并发数较大时,需要创建大量线程来处理连接,系统资源占用较大
- 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费
2.3、NIO(同步非阻塞)
同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求就进行处理
2.4、AIO(异步非阻塞)
AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用
Proactor 模式是一个消息异步通知的设计模式,Proactor 通知的不是就绪事件,而是操作完成事件,这也就是操作系统异步 IO 的主要模型。
2.5、BIO、NIO、AIO 适用场景分析
- BIO(同步并阻塞) 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序简单易理解
- NIO(同步非阻塞) 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等。编程比较复杂,JDK1.4 开始支持
- AIO(异步非阻塞) 方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用 OS 参与并发操作, 编程比较复杂,JDK7 开始支持。
边栏推荐
猜你喜欢
Huawei mobile phone one-click to open "maintenance mode" to hide all data and make mobile phone privacy more secure
STM32 full series development firmware installation guide under Arduino framework
ThreadLocal
Apache EventMesh 分布式事件驱动多运行时
All-platform GPU general AI video supplementary frame super-score tutorial
MySQL - single function
How can we improve the real yourself, become an excellent architect?
九齐ny3p系列语音芯片替代国产方案KT148A性价比更高420秒长度
The new telecom "routine", my dad was tricked!
flyway的快速入门教程
随机推荐
MySQL---operator
Flex布局详解
How to change npm to Taobao mirror [easy to understand]
手把手教你学会部署Nestjs项目
iNeuOS工业互联网操作系统,设备运维业务和“低代码”表单开发工具
MySQL - single function
ojdbc8 "Recommended Collection"Teach you how to deploy Nestjs projects
九齐ny3p系列语音芯片替代国产方案KT148A性价比更高420秒长度
全网一触即发,自媒体人的内容分发全能助手——融媒宝
MySQL---aggregate function
2022 Android interview summary (with interview questions | source code | interview materials)
pytorch lstm时间序列预测问题踩坑「建议收藏」
Kotlin coroutines: continuation, continuation interceptor, scheduler
useragent在线查找
MySQL---Create and manage databases and data tables
微信小程序的路由拦截
Made with Flutter and Firebase!counter application
程序员如何学习开源项目,这篇文章告诉你
Huawei mobile phone one-click to open "maintenance mode" to hide all data and make mobile phone privacy more secure