【网络协议】聊聊套接字socket

网络编程我们知道是通过socket进行编程的,其实socket也是基于TCP和UDP协议进行编程的。但是在socket层面是感知不到下层的,所以在设置参数的时候,其实是端到端协议智商的网络层和传输层。TCP是数据流所以设置为SOCK_STREAM,而UDP是基于数据报的,设置为SOCK_DGRAM

基于 TCP 协议的 Socket 程序函数调用过程

整体流程其实就是显示服务端进行bind ip+端口 可以进一步确定机器和将数据发送给那个应用程序,然后就开始监听状态。

在内核中,为每个 Socket 维护两个队列。一个是已经建立了连接的队列,这时候连接三次握手已经完毕,处于 established 状态;一个是还没有完全建立连接的队列,这个时候三次握手还没完成,处于 syn_rcvd 的状态。

服务端拿出一个已经完成的连接进行处理,客户端通过connect函数创建连接,指明要连接的目标IP+port。内核会给客户端分配一个临时的端口。

监听的 Socket 和真正用来传数据的 Socket 是两个,一个叫作监听 Socket,一个叫作已连接 Socket。
连接建立完成,就通过一写一读的模式进行处理数据。

Socket 在 Linux 中就是以文件的形式存在的。除此之外,还存在文件描述符。写入和读出,也是通过文件描述符。
在这里插入图片描述

基于 UDP 协议的 Socket 程序函数调用过程

UDP因为不需要进行连接,所以只需要端口和IP使用senddtp就可以发送数据,recvfrom接收数据。
在这里插入图片描述

服务器如何接更多的项目?

因为上面的方式其实就是一个客户端对应一个服务端的模式,但是对于高性能、高并发系统来说,其实都是需要一个服务端进行同时处理上千上万的客户端请求处理,所以这种方式不可以,那么服务端最大TCP连接数其实是受到文件描述符限制 也就是ulimit 文件描述符的数目,另一个就是内存,每个TCP连接都要占用一定的内存,硬件资源也是有限制的。

多进程方式

一种方式就是有一个专门处理连接+转发任务的进程,但是当有新的客户端请求进来的时候,这个主进程会fork新的进程进行处理客户端的请求,因为是通过frok的形式,所以会复制文件描述符的列表,也会复制内存空间。所以子进程也可以访问内核态统一打开文件列表的文件,当子进程处理完毕之后,就可以通过函数的返回值进行判断。如果是整数就是父进程,如果是0就是子进程。

在这里插入图片描述

多线程方式

线程相比进程暂用的资源更少,但是对于C10K问题来说,其实还有有点捉襟见肘。

IO 多路复用

select模式
由于socket是文件描述符,所以可以通过一个线程进行所有的文件描述符,将所有的文件描述符放在一起,fd_set中,会实时监听,那些文件描述符有变化,当发生变化的时候就将fd_set设置为1,表示socket可读或者可写,然后继续调用select进行监听下一轮的变化。

epollo
因为监听这种方式需要遍历所有的文件描述符,并且有最大数据限制。
所以最好的方式是那个文件描述符有变化,进行主动通知的方式,在内核的实现方式不是通过轮训的方式,而是通过注册callback函数的方式,当某个文件描述符发送变化的时候,主动通知。
在这里插入图片描述
比如创建了m n x三个socket。那么会先创建一个epoll对象,也就是一个文件描述符,对应结构其实就是一个红黑树,保存所有这个监听所有的socket。当添加一个socket的时候,其实就是加入这个红黑树,红黑树的节点指向这个结构,将这个结构挂在被监听的socket事件列表中,当一个socket来了一个事件的时候,就可以从列表中获取epoll对象,并调用call back进行回调。
epoll 被称为解决 C10K 问题的利器

小结

本篇主要介绍了UDP和TCP网络编程流程细节,以及支撑大量连接的高并发的服务端不容易,多进程、多线程、IO多路复用等。

推荐阅读:https://blog.csdn.net/jia970426/article/details/130611163?spm=1001.2014.3001.5501

[https://blog.csdn.net/jia970426/article/details/132947333?spm=1001.2014.3001.5501]

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

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

相关文章

【Linux】——使用yum进行软件安装和卸载Win和Linux文件交互

个人主页点击直达:小白不是程序媛 Linux系列专栏:Linux被操作记 目录 前言: Linux软件包管理器yum 什么是软件包 ​编辑软件查找 如何安装软件 如何卸载软件 lrzsz的使用 将Windows的文件传送到Linux 将Linux的文件传送到Windows …

C++ 自引用指针this(整理)

使用例子&#xff1a; #include <iostream> #include <Windows.h> using namespace std; class A { public:A(int x1){x x1;}void disp(){cout<<"this"<<this<<" when x"<<this->x<<endl;} private:int x;…

Go学习第十四章——Gin请求与响应

Go web框架——Gin请求与响应 1 响应1.1 String1.2 JSON&#xff08;*&#xff09;1.3 HTML&#xff08;*&#xff09;1.4 XML1.5 文件&#xff08;*&#xff09; 2 请求2.1 请求参数查询参数 (Query)动态参数 (Param)表单参数 (PostForm)原始参数 (GetRawData) 2.2 请求头2.3 …

【2023.10.30练习】C语言-循环右移字符

计算机能力挑战初赛2020.19题 题目描述&#xff1a; 现要对一个由字符a-z和A-Z组成的字符串进行解密&#xff0c;已知加密规则是&#xff1a; 字符串中所有字符分别在大写或小写的字母表中被循环左移5位(fGh-->aBc)&#xff0c; 输入&#xff1a;一个加密过的字符串&#…

GO学习之 通道(nil Channel妙用)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…

【unity3D】Rect Transform组件

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的Rect Transform组件 Rect Transform组件 基础知识详细介绍补充 基础知识 Rect Transform是Unity中的一个UI组件&#xff0c;用于…

RabbitMQ消费者的可靠性

目录 一、消费者确认 二、失败重试机制 2.1、失败处理策略 三、业务幂等性 3.1、唯一消息ID 3.2、业务判断 3.3、兜底方案 一、消费者确认 RabbitMQ提供了消费者确认机制&#xff08;Consumer Acknowledgement&#xff09;。即&#xff1a;当消费者处理消息结束后&#x…

synchronized 同步锁的思考

经过前面的分析&#xff0c;我们大概对同步锁有了一些基本的认识&#xff0c;同步锁的本质就是实现多线程的互斥&#xff0c;保证同一时刻只有一个线程能够访问加了同步锁的代码&#xff0c;使得线程安全性得到保证。下面我们思考一下&#xff0c;为了达到这个目的&#xff0c;…

Linux 块设备驱动实验

前面我们都是在学习字符设备驱动&#xff0c;本章我们来学习一下块设备驱动框架&#xff0c;块设备驱动是 Linux 三大驱动类型之一。块设备驱动要远比字符设备驱动复杂得多&#xff0c;不同类型的存储设备又 对应不同的驱动子系统&#xff0c;本章我们重点学习一下块设备相关驱…

图像分类任务ViT与CNN谁更胜一筹?DeepMind用实验证明

精华置顶 墙裂推荐&#xff01;小白如何1个月系统学习CV核心知识&#xff1a;链接 点击CV计算机视觉&#xff0c;关注更多CV干货 今天跟大家分享DeepMind发表的一篇技术报告&#xff0c;通过实验得出&#xff0c;CNN与ViT的架构之间虽然存在差异&#xff0c;但同等计算资源的预…

人工智能AI 全栈体系(九)

第一章 神经网络是如何实现的 如何用神经网络处理不等长文本的方法&#xff1f; 八、循环神经网络&#xff08;RNN: Recurrent Neural Network&#xff09; 处理不等长文本的神经网络 – 循环神经网络 RNN。 1. 从句子理解说起 上次讲了用词向量表示词&#xff0c;一句话也…

北邮22级信通院数电:Verilog-FPGA(7)第七周实验(2):BCD七段显示译码器(关注我的uu们加群咯~)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 关注作者的uu们可以进群啦~ 目录 一.verilog代码…

Kubernetes Label Selector

Author&#xff1a;rab 目录 前言一、Labels1.1 定义1.2 案例1.2.1 节点标签1.2.2 对象标签 二、Selector2.1 Node Selector2.2 Service Selector2.3 Deployment Selector2.4 StatefulSet Selector2.5 DaemonSet Selector2.6 HorizontalPodAutoscaler Selector2.7 NetworkPolic…

【C】柔性数组

柔性数组 也许你从来没有听说过柔性数组&#xff08;flexible array)这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做『柔性数组』成员。 例如&#xff1a; 柔性数组的特点 结构中的柔性数组成员前…

ZKP7.1 Polynomial Commitments Based on Error-correcting Codes (Background)

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 7: Polynomial Commitments Based on Error-correcting Codes (Yupeng Zhang) Recall: common paradigm for efficient SNARK A polynomial commitment scheme A polynomial interactive oracle proof (IOP) SNARK for gene…

CAN总线通信协议

Reference video: 趋近于完美的通讯 CAN总线&#xff01;4分钟看懂&#xff01; CAN通信精华整理&#xff0c;汽车工程师必备技能&#xff0c;一个视频带你轻松掌握&#xff01; 写在前面&#xff1a;CAN通信就三个要点 - 波特率的配置 - 过滤寄存器的配置与理解&#xff08;…

数组与链表算法-单向链表算法

目录 数组与链表算法-单向链表算法 C代码 单向链表插入节点的算法 C代码 单向链表删除节点的算法 C代码 对单向链表进行反转的算法 C代码 单向链表串接的算法 C代码 数组与链表算法-单向链表算法 在C中&#xff0c;若以动态分配产生链表节点的方式&#xff0c;则可以…

“第五十五天”

定点数&#xff1a; 原码的乘法&#xff1a; 乘法的符号位是单独处理的&#xff08;通过对被乘数和乘数的符号位进行异或实现&#xff09;&#xff0c;数值位去绝对值进行运算。这里的乘法实际上是通过多次加法实现的。 这里被乘数是放在x寄存器&#xff0c;乘数放在MQ寄存器…

【音视频|wav】wav音频文件格式详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

洛谷 B2009 计算 (a+b)/c 的值 C++代码

目录 题目描述 AC Code 切记 题目描述 题目网址&#xff1a;计算 (ab)/c 的值 - 洛谷 AC Code #include<bits/stdc.h> using namespace std; int main() {int a,b,c;cin>>a>>b>>c;cout<<(ab)/c<<endl;return 0; } 切记 不要复制题…