分布式架构下 网络通信的底层实现原理(三)

阻塞通信

Java中经常会使用Scoket套接字来实现网通信,

举个栗子:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class testSocket {public static void main(String[] args) throws IOException {final int DEFAULT_PORT = 8080;ServerSocket serverSocket = null;serverSocket = new ServerSocket(DEFAULT_PORT);System.out.println("启动服务,监听端口:" + DEFAULT_PORT);while (true) {Socket socket = serverSocket.accept();System.out.println("客户端:" + socket.getPort() + "已连接");new Thread(new Runnable() {Socket socket;public Runnable setSocket(Socket s){this.socket=s;return this;}@Overridepublic void run() {try {BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String clientStr = null; //读取一行信息clientStr = bufferedReader.readLine();System.out.println("客户端发了一段消息:" + clientStr);BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bufferedWriter.write("我已经收到你的消息了");bufferedWriter.flush(); //清空缓冲区触发消息发送} catch (IOException e) {e.printStackTrace();}}}.setSocket(socket)).start();}}
}

 上面这个实例就是BIO模型,也就是阻塞通信模型,它会等待客户端建立连接,并且等待客户端的数据传输

阻塞的本质

阻塞是指进程在等待某个事件发生之前的等待状态,它是属于操作系统层面的调度,我们通过下面操作来追踪Java程序中有多少程序,每一个线程对内核产生了哪些操作。

strace,Linux操作系统中的指令

  1. 把ServerSocketExample.java,去掉package导入头,拷贝到linux服务器的 /data/app目录下。

  2. 使用javac ServerSocketExample.java进行编译,得到.class文件

  3. 使用下面这个命令来追踪(打开一个新窗口)

    按照strace官网的描述, strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。

    strace -ff -o out java ServerSocketExample
    • -f 跟踪目标进程,以及目标进程创建的所有子进程

    • -o 把strace的输出单独写到指定的文件

  4. 上述指令执行完成后,会在/data/app目录下得到很多out.*的文件,每个文件代表一个线程。因为Java本身是多线程的。

[root@localhost app]# ll
total 748
-rw-r--r--. 1 root root 14808 Aug 23 12:51 out.33320 //最小的表示主线程
-rw-r--r--. 1 root root 186893 Aug 23 12:51 out.33321
-rw-r--r--. 1 root root 961 Aug 23 12:51 out.33322
-rw-r--r--. 1 root root 917 Aug 23 12:51 out.33323
-rw-r--r--. 1 root root 833 Aug 23 12:51 out.33324
-rw-r--r--. 1 root root 819 Aug 23 12:51 out.33325
-rw-r--r--. 1 root root 23627 Aug 23 12:53 out.33326
-rw-r--r--. 1 root root 1326 Aug 23 12:51 out.33327
-rw-r--r--. 1 root root 1144 Aug 23 12:51 out.33328
-rw-r--r--. 1 root root 1270 Aug 23 12:51 out.33329
-rw-r--r--. 1 root root 8136 Aug 23 12:53 out.33330
-rw-r--r--. 1 root root 8158 Aug 23 12:53 out.33331
-rw-r--r--. 1 root root 6966 Aug 23 12:53 out.33332
-rw-r--r--. 1 root root 1040 Aug 23 12:51 out.33333

 

 5.打开out.33321这个文件(主线程后面的一个文件),shift+g到该文件的尾部,可以看到如下内容。

下面这些方法,都是属于系统调用,也就是调用操作系统提供的内核指令触发相关的操作。

# 创建socket fd 
socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 5 
....
# 绑定8888端口
bind(5, {sa_family=AF_INET6, sin6_port=htons(8888), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
# 创建一个socket并监听申请的连接, 5表示sockfd,50表示等待队列的最大长度
listen(5, 50)                           = 0
mprotect(0x7f21d00df000, 4096, PROT_READ|PROT_WRITE) = 0
write(1, "\345\220\257\345\212\250\346\234\215\345\212\241\357\274\214\347\233\221\345\220\254\347\253\257\345\217\243\357\274\23288"..., 34) = 34
write(1, "\n", 1)                       = 1
lseek(3, 58916778, SEEK_SET)            = 58916778
read(3, "PK\3\4\n\0\0\10\0\0U\23\213O\336\274\205\24X8\0\0X8\0\0\25\0\0\0", 30) = 30
lseek(3, 58916829, SEEK_SET)            = 58916829
read(3, "\312\376\272\276\0\0\0004\1\367\n\0\6\1\37\t\0\237\1 \t\0\237\1!\t\0\237\1\"\t\0"..., 14424) = 14424
# poll, 把当前的文件指针挂到等待队列,文件指针指的是fd=5,简单来说就是让当前进程阻塞,直到有事件触发唤醒
* events: 表示请求事件,POLLIN(普通或优先级带数据可读)、POLLERR,发生错误。
poll([{fd=5, events=POLLIN|POLLERR}], 1, -1

 

从这个代码中可以看到,Socket的accept方法最终是调用系统的poll函数来实现线程阻塞的。

通过在linux服务器输入 man 2 poll

man: 帮助手册

2:表示系统调用相关的函数

DESCRIPTIONpoll()  performs  a  similar  task  to  select(2): it waits for one of a set of filedescriptors to become ready to perform I/O.

poll类似于select函数,它可以等待一组文件描述符中的IO就绪事件

  6.通过下面命令访问socket server。

telnet 192.168.221.128 8888

这个时候通过tail -f out.33321这个文件,发现被阻塞的poll()方法,被POLLIN事件唤醒了,表示监听到了一次连接。

poll([{fd=5, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=5, revents=POLLIN}])
accept(5, {sa_family=AF_INET6, sin6_port=htons(53778), inet_pton(AF_INET6, "::ffff

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

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

相关文章

web自动化测试框架都是有哪些?

Web自动化测试框架主要有以下几种: 1.Selenium:轻量级的Web自动化测试框架,支持多种Web浏览器和语言的集成。Selenium提供了一个IDE来录制和运行自动化测试脚本,还提供了WebDriver,可以通过编程语言编写自动化测试脚本…

【鸿蒙 HarmonyOS 4.0】Web组件

一、介绍 页面加载是Web组件的基本功能。根据页面加载数据来源可以分为三种常用场景,包括加载网络页面、加载本地页面、加载HTML格式的富文本数据。 二、加载网页 2.1、加载在线网页 Web组件的使用非常简单,只需要在Page目录下的ArkTS文件中创建一个…

5款好用的AI办公软件,一键轻松制作PPT、视频,提升工作效率!

众所周知,AI 人工智能技术已渗透到生活的方方面面,无论是很多人早已用上的智能音箱、语音助手,还是新近诞生的各种 AI 软件工具,背后都离不开 AI 人工智能技术的加持。 对于各类新生的 AI 软件工具,人们很容易「选边站…

Go的安装

一. 下载地址 Go官方下载地址:https://golang.org/dl/ Go中文网:https://go.p2hp.com/go.dev/dl/ 根据不同系统下载不同的包。 二. 配置GOPATH GOPATH是一个环境变量,用来表明你写的go项目的存放路径。 GOPATH路径最好只设置一个&#xff0…

部署 Web 项目到Linux上

目录 环境配置 构建项目 ​编辑 数据准备 运行并查看日志 杀掉进程 把程序安装到生产环境上, 这个过程称为 "部署",也叫 "上线"。一旦程序部署成功, 那么这个程序就能被外网中千千万万的普通用户访问到。 环境配置 程序配置文件修改 实…

网络套接字1

网络套接字1 📟作者主页:慢热的陕西人 🌴专栏链接:Linux 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 本博客主要内容讲解了udp的Linux环境下的使用&#xff0c…

有线网络下windows电脑被投屏方案实践

最近在看使用笔记本屏幕作PC副屏的解决方案 无线网络Miracast 如果使用Win10/11自带的Miracast方案(即windows系统中的:设置-系统-投影到此电脑),原则上需要通过Wi-Fi网络(这是因为Miracast就是Wi-Fi联盟组织提出的&a…

react-native 搭建环境及运行项目

目前创建的是0.73版本的,Node 的版本应大于等于 18,需要 Java Development Kit [JDK] 17版本的(必须是17版本)。安装完后你可以在命令行中输入 javac -version(请注意是 javac,不是 java)来查看…

一键优化B2B2C电商系统,开启无限商机

在当今竞争激烈的电商行业,B2B2C模式已成为众多企业选择的经营模式之一。通过一键优化B2B2C电商系统,企业能够开启无限商机,实现更大的发展空间。 首先,优化B2B2C电商系统可以帮助企业提升用户体验,吸引更多客户。通过…

仿生蝴蝶制作——蝴蝶翅膀制作

前言 上一次已经设计好了的翅膀图纸 接下来就是根据这个图纸来制作翅膀。 过程中其实可以不用尺子准确测量,直接用碳纤维棒比着剪下来就好了,然后把减下来的一截比着剪下另一只翅膀需要的材料。因为左右两只翅膀差别不能太大,所以这样是最好…

异步编程和asyncio

介绍异步编程的重要性和在Python中的应用,特别是在I/O密集型任务和网络编程场景下。 目录 理解异步编程 异步编程基本概念 任务与Future 异步编程的工作原理 事件循环 协程(Coroutines) 异步与同步代码的结合 深入asyncio模块 事件循…

CCF-C推荐会议 IEEE CLOUD‘24 3月24日截稿!深圳开启全球云计算新纪元!

会议之眼 快讯 IEEE CLOUD(IEEE International Conference on Cloud Computing)即IEEE云计算国际会议将于 2024 年7月7日至13日在中国深圳举行!IEEE CLOUD由lEEE Computer Society主办,CCF服务计算专委会、北京大学、IBM Research承办。CLOUD一直是研究人…

软件测试APP完整测试作业流程(附流程图),公司级软件测试流程化办公

目录 1. 概述 2. 软件测试流程 3. 软件测试周期人员活动图 4. 总结 1. 概述 1.1 目的 有效的保证软件质量; 有效的制定不同测试类型(软件系统测试、音频主观性测试、Field Trial、专项测试、自动化测试、性 能测试、用户体验测试)的软件…

【框架设计】MVC和MVVM对比图

1. MVC(Model-View-Controller) 单向通信View和Model通过Controller承上启下 2. MVVM(Model-View-ViewModel) 数据绑定M -> VM -> V DOM事件监听 V -> VM -> M 1. MVC是单向的,MVVM是双向的,…

【SpringCloud微服务全家桶学习笔记-GateWay网关(微服务入口)】

Gateway服务网关 API网关为微服务架构中的服务提供了统一的访问入口,客户端通过API网关访问相关服务。API网关的定义类似于设计模式中的门面模式,它相当于整个微服务架构中的门面,所有客户端的访问都通过它来进行路由及过滤。它实现了请求路…

二 超级数据查看器   讲解稿   导入功能

二 超级数据查看器 讲解稿 导入功能 APP下载地址 百度手机助手 下载地址4 ​ 讲解稿全文: 大家好。 今天我们对 超级数据查看器的 导入信息功能 做一下详细讲解。 首先,我们打开 超级数据查看器。 我们这个系统要实现的是,快速生…

GEE:基于Landsat8计算陆地表面温度(Land Surface Temperature,LST)

作者:CSDN _养乐多_ 本文将介绍在Google Earth Engine(GEE)平台上使用 Landsat 8 卫星影像数据计算陆地表面温度(Land Surface Temperature,LST)的代码。 结果如下图所示, 文章目录 一、参考…

阿里P8解析自动化测试工具 —— SeleniumAppium!

自动化测试,利用自动化测试工具,通过录制/编程方式实现测试活动,发现被测对象存在的缺陷,从而替代手工测试活动。自动化测试不局限于某个具体测试阶段,也不局限被测对象的类型,只要满足自动化测试的必要条件…

数据库--SQL语言-1

练习网站:自学SQL网 Select 查询语法复习 SELECT column, another_column, …FROM mytableWHERE condition AND/OR another_condition AND/OR …; 操作符号: 如果属性是字符串, 我们会用到字符串相关的一些操作符号,其中 LIKE&#xff08…

day04-Maven-SpringBootWeb入门

文章目录 01. Maven1.1 课程安排1.2 什么是Maven1.3 Maven的作用1.4 Maven模型1.5 Maven仓库1.6 Maven安装1.6.1 下载1.6.2 安装步骤 2 IDEA集成Maven2.1 配置Maven环境2.1.1 当前工程设置2.1.2 全局设置 2.2 创建Maven项目2.3 POM配置详解2.4 Maven坐标详解2.5 导入Maven项目 …