秋招突击——8/15——知识补充——Socket通信
文章目录
- 引言
- 正文
- 基于TCP协议的Socket通信
- 基于UDP协议的Socket通信
- 服务端如何接收更多项目
- 多进程
- 多线程
- IO多路复用==select轮询
- IO多路复用==epoll事件通知
- 使用Socket实现同一个机器上的多线程通信
- 服务端创建对应socket监听端口
- 客户端发起对应的连接请求
- 总结
引言
- 上次面试腾讯的时候,反复提到了socket通信,不仅仅是不同机器不同进程之间的通信,同一个机器上不同进程之间的通信也是用这个,用的比较广泛,这里是我的知识盲区了,感觉面经上看到过好几次了,这里还是总结一下!补充一下
- 信息来源
正文
- Socket通信是进行端到端的通信,对于下层经过多少局域网、路由器是透明的。
- 进行Socket通信需要指定两个地方,分别是使用IP层协议和传输层协议!
- IP层协议
- IPv4==AF_INET
- IPv6==AF_INET6
- 传输层协议
- TCP》》基于字节流》》SOCK_STREAM
- UDP》》基于数据报》》SOCK_DGRAM
- IP层协议
基于TCP协议的Socket通信
-
在服务端进行Socket通信时,会维护两个Socket,一个是监听的Socket,还有一个是专门用来通信的已连接的Socket通信
- 监听Socket
- 服务器用来监听客户端链接请求的Socket,会一直等待连接请求,常规的监听8080端口
- 已连接Socket
- 当某一个客户端连接到服务器后,服务器会为客户端A生成一个新的Socket
- 监听Socket
-
此后,客户端A和服务器之间的消息传输都是通过这个已有连接的Socket进行,监听Socket继续等待其他客户端的连接请求
1、服务端设置监听Socket步骤
- bind
- 绑定IP地址和端口
- listen
- 服务端进入监听状态,客户端可以进行发起连接,当前的监听Socket会陷入阻塞
- 维系两个队列
- established状态的全连接队列
- syn_rcvd状态的半链接队列
- accept
- 返回一个新的已经建立的Socket,进行数据传输
2、服务器端创建通信Socket过程
- accept
- 创建一个新的socket,这个socket是表示服务器和某一个特定客户端的连接
- 当前链接的标识[客户端IP,客户端端口,监听Socket的IP,监听Socket的端口]
- send和revc
- 通过这三个数据进行手法数据
3、客户端发起连接创建Socket的过程
- connect
- 通过connect发起连接,指定目标IP地址和端口号
- 内核临时为客户端分配一个端口,进行三次握手
Socket的发送接收的底层实现
-
在Linux中是以文件的形式存在的,有对应的文件描述符,写入和读出都是通过文件描述符
- 每一个Socket中都有两个队列,分别是发送队列和接受队列
- 每一个队列保存完整的数据包
-
进程和文件的关系
- 每一个进程都有自己的task_struct,指向能够操作的文件描述符数组,每一个元素是指向内核中打开的文件的列表
- 进程通过操作对应文件结构,进行调用Socket进行发送数据和接受数据
基于UDP协议的Socket通信
- UDP通信比起TCP通信,有以下几个差异
- 没有链接
- 不需要三次握手,不需要在额外创建一个socket通信
- 不用调用listen和connect
- 直接bind即可,开启监听端口等
- 只需要使用sendto和recvfrom进行接收即可!
- 没有链接
服务端如何接收更多项目
- 最大连接数计算
- 标识连接的唯一标志——四元组
- {本机IP,本机端口,目标IP,目标端口}
- 2的32次方,2的16次方,最大连接数是2的48次方
- 受限因素
- 文件描述符限制,系统中ulimit限制
- 内存限制,每一个TCP链接都要占用内存,内存有限
多进程
-
实现
- 每次接收到一个新的socket,就会创建一个新的子进程解决
-
具体实现
- 父进程调用Fork创建子进程,执行如下操作
- 复制一个文件描述符列表
- 复制内存空间
- 指令计数器:当前程序运行的位置
- 父进程因为刚才accept创建的已经链接的Socket,也是一个文件描述符,同样会被子进程获得
- 子进程完成任务,通信完毕之后,退出返回0,标识自己是子进程
- 父进程调用Fork创建子进程,执行如下操作
多线程
-
实现
- 每次创建一个新的连接,创建一个新的socket,就创建一个新的线程解决
-
具体实现
- 主线程调用的pthread_create创建一个新的线程
- 新线程共享进程的资源
- 新线程通过通过已经连接的Socket请求,完成通信
- 主线程调用的pthread_create创建一个新的线程
没有办法解决C10K问题
IO多路复用==select轮询
-
实现
- 一个线程负责所有的Socket,依次查看每一个Socket,进行读写操作
-
具体实现
- Socket本身是文件描述符,保存在一个文件描述符集合中fd_set中
- 调用select函数,轮询所有的文件描述符是否有变化
- 将发生变化的文件描述符状态位设置为1
IO多路复用==epoll事件通知
- 同样都是多路复用,只不过这里的调用函数不一样,是使用epoll的方式,这里仅仅总结一下对应的差异就行了
- 注册通知替换轮询
- epoll_create创建监听的epoll对象
- 通过callback函数的方式,当某一个文件描述符发生变化的时候,主动通知
- 红黑树保存socket
- epoll_ctl实现节点加入红黑树
- 将需要监听的节点加入到红黑树中,快速定位发生时间的节点,然后进行监听。
- 注册通知替换轮询
使用Socket实现同一个机器上的多线程通信
服务端创建对应socket监听端口
- 使用java.net.Socket进行编程
- 创建对应的监听Socket
- 调用对应的accpet函数获取连接
- 每一个连接socket都交给一个新的线程处理
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class Main {private static final int PORT = 12345;public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(PORT)) {System.out.println("Server started on port " + PORT);while (true) {Socket clientSocket = serverSocket.accept();System.out.println("New client connected: " + clientSocket.getInetAddress().getHostAddress());// 每个连接交给一个新的线程处理new Thread(new ClientHandler(clientSocket)).start();}} catch (IOException e) {e.printStackTrace();}}
}
处理通信的线程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;public class ClientHandler implements Runnable {private Socket clientSocket;public ClientHandler(Socket socket) {this.clientSocket = socket;}@Overridepublic void run() {try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);) {String message;while ((message = in.readLine()) != null) {System.out.println("Received from client: " + message);out.println("Echo: " + message);if (message.equalsIgnoreCase("exit")) {break;}}} catch (IOException e) {e.printStackTrace();} finally {try {clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}
}
客户端发起对应的连接请求
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;public class Main {private static final String SERVER_ADDRESS = "localhost";private static final int SERVER_PORT = 12345;public static void main(String[] args) {try (Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);PrintWriter out = new PrintWriter(socket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {String userInput;while ((userInput = stdIn.readLine()) != null) {out.println(userInput);System.out.println("Server response: " + in.readLine());if (userInput.equalsIgnoreCase("exit")) {break;}}} catch (IOException e) {e.printStackTrace();}}
}
总结
- 今天大概了解了Socket通信的相关内容,下次再遇到类型的题目,大差不差,都有一点印象,在考到,再拿过来复习就行了!
- 主要有以下几个部分
- Socket通信在TCP连接中的应用
- Socket通信在UDP连接中的应用
- 如何解决多个Socket通信的问题
- 本地如何使用Socket通信进行通信
相关文章:

秋招突击——8/15——知识补充——Socket通信
文章目录 引言正文基于TCP协议的Socket通信基于UDP协议的Socket通信服务端如何接收更多项目多进程多线程IO多路复用select轮询IO多路复用epoll事件通知 使用Socket实现同一个机器上的多线程通信服务端创建对应socket监听端口客户端发起对应的连接请求 总结 引言 上次面试腾讯的…...

Qt第十四章 模型视图
Model/View(模型/视图)结构 文章目录 Model/View(模型/视图)结构简介视图组件Model/View结构的一些概念项目控件组(item Widgets)模型/视图 如何使用项目视图组设置行的颜色交替变换拖拽设置编辑操作其他操作 选择模型自定义选择多…...
硬件工程师必须掌握的MOS管详细知识
MOS管,全称为金属-氧化物半导体场效应晶体管(Metal-Oxide-Semiconductor Field-Effect Transistor,MOSFET),是一种重要的半导体器件,广泛应用于电子工业中各种电路的开关、放大、调制、数字电路和模拟电路等…...

希尔排序,详细解析(附图解)
1.希尔排序思路 希尔排序是一种基于插入排序的算法,通过将原始数据分成若干个子序列,然后对子序列进行插入排序,逐渐减小子序列的间隔,最后对整个序列进行一次插入排序。 1.分组直接插入排序,目标接近有序--------…...

【C语言篇】编译和链接以及预处理介绍(下篇)
文章目录 前言#和###运算符##运算符 命名约定#undef命令⾏定义条件编译#if和#endif多个分支的条件编译判断是否被定义嵌套指令 头文件被包含头文件被包含的方式本地文件包含库文件的包含 嵌套文件包含 其他预处理指令 写在最后 前言 本篇接前一篇【C语言篇】编译和链接以及预处…...
利用Llama2 7b自己实现一套离线AI
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家, 可以当故事来看,轻松学习。 离了 ChatGPT 本人简直寸步难行,今天 ChatGPT 大面积宕机,服务直到文章写作&am…...

Ciallo~(∠・ω・ )⌒☆第十七篇 Ubuntu基础使用 其一
Ubuntu是一种基于Linux的操作系统,它是开源的、免费的,并且具有广泛的用户群体。 基本文件操作:Ubuntu使用命令行工具来进行文件操作。以下是一些常用的命令: 切换到用户主目录: cd ~ 切换到上级目录: cd .…...
Linux-零拷贝技术
什么是零拷贝? 在传统的数据传输过程中,数据需要从磁盘读取到内核空间的缓冲区,然后再从内核空间拷贝到用户空间的应用程序缓冲区。如果需要将数据发送到网络,数据还需要再次从用户空间拷贝到内核空间的网络缓冲区。这个过程涉及…...

小区团购管理
TOC springboot254小区团购管理 第1章 绪论 1.1选题动因 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔记本的广泛运用&…...

图像文本擦除无痕迹!复旦提出EAFormer:最新场景文本分割新SOTA!(ECCV`24)
文章链接:https://arxiv.org/pdf/2407.17020 git链接:https://hyangyu.github.io/EAFormer/ 亮点直击 为了在文本边缘区域实现更好的分割性能,本文提出了边缘感知Transformer(EAFormer),该方法明确预测文…...

Codeforces Round 966 (Div. 3)(A,B,C,D,E,F)
A. Primary Task 签到 void solve() {string s;cin>>s;bool bltrue;if(s.size()<2)blfalse;else{if(s.substr(0,2)"10"){if(s[2]0)blfalse;else if(s[2]1&&s.size()<3)blfalse; }else blfalse;}if(bl)cout<<"YES\n";else cout…...
【代码随想录算法训练营第42期 第六天 | LeetCode242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和】
代码随想录算法训练营第42期 第六天 | LeetCode242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和 一、242.有效的字母异位词 解题代码C: bool isAnagram(char* s, char* t) {int len1 strlen(s);int len2 strlen(t);int al[26] {0};int b…...

WebRTC音视频开发读书笔记(一)
一、基本概念 WebRTC(Web Real-Time Communication,网页即时通信)于2011年6月1日开源,并被纳入万维网联盟的W3C推荐标准,它通过简单API为浏览器和移动应用提供实时通信RTC功能。 1、特点 跨平台:可以在Web,Android、…...

llama3.1本地部署方式
llama3.1 资源消耗情况 Llama 3.1 - 405B、70B 和 8B 的多语言与长上下文能力解析  70B版本,FP1616K token需要的资源约为75G;FP16128K token需要的资源约为110G  1、ollama ollama工具部署及使用…...
相机光学(三十四)——色差仪颜色观察者视角
1.为什么会有观察者视角 颜色观察角度主要涉及到人眼观察物体时,视角的大小以及屏幕显示颜色的方向性对颜色感知的影响。 人眼观察物体的视角:在黑暗条件下,人眼主要依靠杆体细胞来分辨物体的轮廓,而杆体细胞分布在视网…...
思二勋:web3.0是打造应对复杂市场敏捷组织的关键
本文内容摘自思二勋所著的《分布式商业生态战略》一书。 数字化时代,需要企业具备敏捷应对变化的能力,以敏捷反应应对客户和市场的迅速变化。敏捷能力的建设需要触点网络、信息系统、IT 架构、业务流程等同时实现敏捷。尤其是在多变且复杂环境中,特别要求战略管理的敏捷性和…...

一文带你快速了解——HAProxy负载均衡
一、HAProxy简介 1.1、什么是Haproxy HAProxy是法国开发者 威利塔罗(Willy Tarreau)在2000年使用C语言开发的一个开源软件是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计。…...

【C++高阶】哈希—— 位图 | 布隆过滤器 | 哈希切分
✨ 人生如梦,朝露夕花,宛若泡影 🌏 📃个人主页:island1314 🔥个人专栏:C学习 ⛺️ 欢迎关注:👍点赞 👂&am…...

启发式算法之模拟退火算法
文章目录 1. 模拟退火算法概述1.1 算法起源与发展1.2 算法基本原理 2. 算法实现步骤2.1 初始化过程2.2 迭代与降温策略 3. 模拟退火算法的优化策略3.1 冷却进度表的设计3.2 参数调整与策略 4. 模拟退火算法的应用领域4.1 组合优化问题4.1.1 旅行商问题(TSPÿ…...

编码器汇总:光学编码器,霍尔编码器,磁性编码器,电容式编码器,单圈编码器,多圈编码器,增量式编码器,绝对值式编码器等
系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 前言一、光学编码器二、霍尔编码器三、磁性编码器四、电容式编码器五、单圈编码器六、多圈编码器七、增量式编码器八、…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...