NIO和BIO编程

一、网络通信编程基本常识

1、什么是Socket?

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,一般由操作系统提供。

2、短连接

短连接是指socket建立连接之后传输数据确定接收完后关闭连接

3、长连接

长连接是指建立socket连接后不管是否使用都保持连接

4、什么时候用长连接,短连接?

http1.1网上都开始向长连接演化,web网站成千上万的客户端使用短连接会更节省资源消耗,短连接频繁的通信会造成socket错误,而socket频繁的创建也会耗费系统资源

二、Java原生网络编程

1、原生JDK网络编程BIO

面向流的阻塞IO,

服务端(这种来一个客户端就创建一个线程的方式,如果客户端连接数量过多,内存资源消耗过多,造成系统崩溃)

public class Server {public static void main(String[] args) throws IOException {// 创建ServerSocket接收客户端连接对象ServerSocket serverSocket = new ServerSocket();// 绑定服务器监听端口serverSocket.bind(new InetSocketAddress(8888));System.out.println("start server...");while (true) {new Thread(new ServerTask(serverSocket.accept())).start();}}private static class ServerTask implements Runnable {private Socket socket = null;public ServerTask(Socket socket) {this.socket = socket;}@Overridepublic void run() {try(//实例化与客户端通信的输入输出流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 {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
}// 单线程实现服务端连接(单线程服务端无法同时支持多个连接同时处理)
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));//实例化与客户端通信的输入输出流try(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 {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}} finally {serverSocket.close();}}
}// 线程池的方式启动服务端(受线程数量影响,如果传输的数据过大 比如文件,占用时间过长的话,其它连接只能等待)
class ServerPool {private static ExecutorService executorService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());public static void main(String[] args) throws IOException {//服务端启动必备ServerSocket serverSocket = new ServerSocket();//表示服务端在哪个端口上监听serverSocket.bind(new InetSocketAddress(10001));System.out.println("Start Server ....");try{while(true){executorService.execute(new ServerTask(serverSocket.accept()));}}finally {serverSocket.close();}}//每个和客户端的通信都会打包成一个任务,交个一个线程来执行private static class ServerTask implements Runnable{private Socket socket = null;public ServerTask(Socket socket){this.socket = socket;}@Overridepublic void run() {//实例化与客户端通信的输入输出流try(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 {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}}

客户端 

public class Client {public static void main(String[] args) throws IOException {Socket socket = null;ObjectOutputStream objectOutputStream = null;ObjectInputStream objectInputStream = null;InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8888);try {socket = new Socket();socket.connect(inetSocketAddress);System.out.println("connect server success");objectOutputStream = new ObjectOutputStream(socket.getOutputStream());objectInputStream = new ObjectInputStream(socket.getInputStream());System.out.println("ready send message");objectOutputStream.writeUTF("gaorufeng");objectOutputStream.flush();// 接收并打印服务器传输的数据System.out.println(objectInputStream.readUTF());} finally {if (socket!=null) socket.close();if (objectOutputStream!=null) objectOutputStream.close();if (objectInputStream!=null) objectInputStream.close();}}
}

BIO阻塞的两个地方:

1、服务端执行serverSocket.accept()方法后会进入阻塞,直到有客户端请求进来

2、服务器如果是单线程运行(一个线程处理多个客户端请求会进入阻塞),如果数据还没传输完毕,其它客户端socket是无法与服务端建立tcp连接的,虽然socket显示连接成功,但是tcp连接还没建立

BIO适合少量连接的使用场景

BIO多线程通信模型:

2、原生JDK网络编程NIO

面向缓冲的非阻塞IO

1)NIO的Reactor模式

BIO和NIO最大的区别就是线程阻塞和不阻塞,NIO就是基于Reactor模式实现的,所谓Reactor模式,就是往一个组件注册感兴趣的事件并监听,触发对应的事件进行处理,而不是阻塞

2)NIO三大核心组件
  1. Selector选择器:Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器(Selectors),然后使用一个单独的线程来操作这个选择器,进而“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道(应用程序将向 Selector 对象注册需要它关注的 Channel,以及具体的某一个 Channel会对哪些 IO 事件感兴趣。Selector 中也会维护一个“已经注册的Channel”的容器)。
  2. Channel管道:被建立的一个应用程序和操作系统交互事件、传递内容的渠道(注意是连接到操作系统)。那么既然是和操作系统进行内容的传递,那么说明应用程序可以通过通道读取数据,也可以通过通道向操作系统写数据,而且可以同时进行读写。
  3. buffer缓冲区:JDK NIO是面向缓冲的。Buffer就是这个缓冲,用于和 NIO 通道进行交互。 数据是从通道读入缓冲区,从缓冲区写入到通道中的。以写为例,应用程序都是将数据写入 缓冲,再通过通道把缓冲的数据发送出去,读也是一样,数据总是先从通道读到缓冲,应用程序再读缓冲的数据。
public class NioSelectorServer {public static void main(String[] args) throws IOException, InterruptedException {// 创建NIO ServerSocketChannelServerSocketChannel serverSocket = ServerSocketChannel.open();serverSocket.socket().bind(new InetSocketAddress(9000));// 设置ServerSocketChannel为非阻塞serverSocket.configureBlocking(false);// 打开Selector处理Channel,即创建epollSelector selector = Selector.open();// 把ServerSocketChannel注册到selector上,并且selector对客户端accept连接操作感兴趣serverSocket.register(selector, SelectionKey.OP_ACCEPT);System.out.println("服务启动成功");while (true) {// 阻塞等待需要处理的事件发生selector.select();// 获取selector中注册的全部事件的 SelectionKey 实例Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();// 遍历SelectionKey对事件进行处理while (iterator.hasNext()) {SelectionKey key = iterator.next();// 如果是OP_ACCEPT事件,则进行连接获取和事件注册if (key.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) key.channel();SocketChannel socketChannel = server.accept();socketChannel.configureBlocking(false);// 这里只注册了读事件,如果需要给客户端发送数据可以注册写事件socketChannel.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接成功");} else if (key.isReadable()) {  // 如果是OP_READ事件,则进行读取和打印SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer byteBuffer = ByteBuffer.allocate(128);int len = socketChannel.read(byteBuffer);// 如果有数据,把数据打印出来if (len > 0) {System.out.println("接收到消息:" + new String(byteBuffer.array()));} else if (len == -1) { // 如果客户端断开连接,关闭SocketSystem.out.println("客户端断开连接");socketChannel.close();}}//从事件集合里删除本次处理的key,防止下次select重复处理iterator.remove();}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/171531.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go RESTful API 接口开发

文章目录 什么是 RESTful APIGo 流行 Web 框架-GinGo HelloWorldGin 路由和控制器Gin 处理请求参数生成 HTTP 请求响应Gin 的学习内容实战用 Gin 框架开发 RESTful APIOAuth 2.0接口了解用 Go 开发 OAuth2.0 接口示例 编程有一个准则——Don‘t Repeat Yourself&#xff08;不要…

vue源码分析(三)——new Vue 的过程(详解data定义值后如何获取的过程)

文章目录 零、准备工作1.创建vue2项目2.修改main.js 一、import Vue from vue引入的vue是哪里来的&#xff08;看导入node_modules包&#xff09;1&#xff1a; 通过node_modules包的package.json文件2&#xff1a; 通过配置中的main入口文件进入开发环境的源码&#xff08;1&a…

java将list转为逗号隔开字符串,将逗号连接的字符串转成字符数组,​将逗号分隔的字符串转换为List​(Java逗号分隔-字符串与数组相互转换)

一、通过testList.stream().collect(Collectors.joining(",")) &#xff0c;通过流转换&#xff0c;将list转为逗号隔开字符串 List<String> testList new ArrayList<>(); testList.add("test1"); testList.add("test2"); testList…

如何查找特定基因集合免疫基因集 炎症基因集

温故而知新&#xff0c;再次看下Msigdb数据库。它更新了很多内容。给我们提供了一个查询基因集的地方。 关注微信&#xff1a;生信小博士 比如纤维化基因集&#xff1a; 打开网址&#xff1a;https://www.gsea-msigdb.org/gsea/msigdb/index.jsp 2.点击search 3.比如我对纤维…

基于Python Django 的微博舆论、微博情感分析可视化系统(V2.0)

文章目录 1 简介2 意义3 技术栈Django 4 效果图微博首页情感分析关键词分析热门评论舆情预测 5 推荐阅读 1 简介 基于Python的微博舆论分析&#xff0c;微博情感分析可视化系统&#xff0c;项目后端分爬虫模块、数据分析模块、数据存储模块、业务逻辑模块组成。 Python基于微博…

如何在Windows和Linux系统上监听文件夹的变动?

文章目录 如何在Windows和Linux系统上监听文件夹的变动&#xff1f;读写文件文件系统的操作缓冲和流文件改变事件 如何在Windows和Linux系统上监听文件夹的变动&#xff1f; libuv库实现了监听整个文件夹的修改。本文详细介绍libuv库文件读写和监听的的实现方法。libuv库开发了…

浏览器事件循环 (event loop)

进程与线程 进程 进程的概念 进程是操作系统中的一个程序或者一个程序的一次执行过程&#xff0c;是一个动态的概念&#xff0c;是程序在执行过程中分配和管理资源的基本单位&#xff0c;是操作系统结构的基础。 简单的来说&#xff0c;就是一个程序运行开辟的一块内存空间&a…

【计算机网络笔记】Cookie技术

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Fourier分析导论——第1章——Fourier分析的起源(E.M. Stein R. Shakarchi)

第 1 章 Fourier分析的起源 (The Genesis of Fourier Analysis) Regarding the researches of dAlembert and Euler could one not add that if they knew this expansion, they made but a very imperfect use of it. They were both persuaded that an arbitrary and d…

如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样,蓝牙接近了电脑,电脑自动解锁无需输入开机密码

环境&#xff1a; Win10 专业版 远程解锁 蓝牙解锁小程序 问题描述&#xff1a; 如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样&#xff0c;蓝牙接近了电脑&#xff0c;电脑自动解锁无需输入开机密码 手机不需要拿出来&#xff0c;在口袋里就可以自动解锁&#xff…

calcite 校验层总结

1、校验的作用 1&#xff09;完善语义信息 例如在SQL语句中&#xff0c;如果碰到select * 这样的指令&#xff0c;在SQL的语义当中&#xff0c;“*” 指的是取出对应数据源中所有字段的信息&#xff0c;因此就需要根据元数据信息来展开。 2&#xff09;结合元数据信息来纠偏…

Java游戏修炼手册:2023 最新学习线路图

前言 有没有一种令人兴奋的学习方法&#xff1f;当然有&#xff01;绝对有&#xff01;而且我要告诉你&#xff0c;学习的快乐可以媲美游戏的刺激。 小学时代&#xff0c;我曾深陷于一款名为"八百万勇士的梦"的游戏。每当放学&#xff0c;我总是迫不及待地打开电脑&a…

JSON(详解)

目录 什么是JSON&#xff1f; 哪里会用到JSON&#xff1f; JSON的特点 JSON的优点 JSON的缺点 JSON和cJSON的关系 什么是JSON&#xff1f; JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式。它以易于阅读和编写的文本格式来存储和表示…

Kafka - 3.x 图解Broker总体工作流程

文章目录 Zk中存储的kafka的信息Kafka Broker总体工作流程1. broker启动后向zk中注册2. Controller谁先启动注册&#xff0c;谁说了算3. 由选举出来的Controller监听brokers节点的变化4. Controller决定leader选举5. Controller将节点信息上传到Zk中6. 其他Controller从zk中同步…

为什么说大模型微调是每个人都必备的核心技能?

▼最近直播超级多&#xff0c;预约保你有收获 近期直播&#xff1a;《基于开源 LLM 大模型的微调&#xff08;Fine tuning&#xff09;实战》 0 — 为什么要对 LLM 大模型进行微调&#xff08;Fine tuning&#xff09;&#xff1f; LLM 大模型&#xff08;比如&#xff1a;Chat…

安全狗安装

安装waf 关闭apache程序及httpd.exe进程; 运行cmd&#xff0c;cd进入apache/bin文件夹目录&#xff0c; 执行httpd.exe -k install -n apache2.4.39; 启动apache,启动phpstudy 安全狗安装服务名称填写apache2.4.39; 安装安全狗之后就会提示报错 网站防护 可以设备黑白名单 漏…

JAVA实现校园二手交易系统 开源

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手商品档案管理模块2.3 商品预约管理模块2.4 商品预定管理模块2.5 商品留言板管理模块2.6 商品资讯管理模块 三、实体类设计3.1 用户表3.2 二手商品表3.3 商品预约表3.4 商品预定表3.5 留言表3.6 资讯…

Leo赠书活动-03期 【ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践 】

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

网络协议--TFTP:简单文件传送协议

15.1 引言 TFTP(Trivial File Transfer Protocol)即简单文件传送协议&#xff0c;最初打算用于引导无盘系统&#xff08;通常是工作站或X终端&#xff09;。和将在第27章介绍的使用TCP的文件传送协议&#xff08;FTP&#xff09;不同&#xff0c;为了保持简单和短小&#xff0…

【微信小程序】数字化会议OA系统之投票模块(附源码)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…