Linux的socket详解

一、本机直接的进程通信方式

  1. 管道(Pipes)

    • 匿名管道(Anonymous pipes):通常用于父子进程间的通信,它是单向的。
    • 命名管道(Named pipes,也称FIFO):允许不相关的进程间进行通信。
  2. 信号(Signals)

    一种较为简单的通信方式,用于处理异步事件。
  3. 共享内存(Shared Memory)

    允许两个或多个进程共享一个给定的存储区,是最快的IPC方式,因为数据不需要在客户和服务器之间复制。
  4. 消息队列(Message Queues)

    消息队列允许一个或多个进程向另一个进程发送格式化的数据块。
  5. 信号量(Semaphores)

    主要用于同步,比如控制多个进程访问共同资源的权限。
  6. 套接字(Sockets)

    虽然通常用于网络通信,但同一台机器上的进程也可以通过本地套接字进行通信。
  7. 内存映射文件(Memory-mapped files)

    将文件或设备直接映射到进程的地址空间中,可被用于进程间的数据共享。

总结:他们都仅限于用在本机进程之间通信。网间进程通信要解决的是不同主机进程间的相互通信问题(可把同机进程通信看作是其中的特例)。为此,首先要解决的是网间进程标识问题。同一主机上,不同进程可用进程号(process ID)唯一标识。

二、网络之间的通信(服务器与客户端)

     但在网络环境下,各主机独立分配的进程号不能唯一标识该进程。例如,主机 A 赋于某进程号 5,在 B 机中也可以存在 5 号进程,因此,“5 号进程” 这句话就没有意义了。其次,操作系统支持的网络协议众多,不同协议的工作方式不同,地址格式也不同。因此,网间进程通信还要解决多重协议的识别问题。

        TCP/IP 协议族已经帮我们解决了这个问题,网络层的 “ip 地址” 可以唯一标识网络中的主机,而传输层的 “协议 + 端口” 可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip 地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

       使用 TCP/IP 协议的应用程序通常采用应用编程接口:UNIX  BSD 的套接字(socket)和 UNIX System V 的 TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用 socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说 “一切皆 socket”。

三、什么是TCP/UDP?

  TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议 / 网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

TCP/IP 协议存在于 OS 中,网络服务通过 OS 提供,在 OS 中增加支持 TCP/IP 的系统调用 ——Berkeley 套接字,如 Socket,Connect,Send,Recv 等 。

 UDP(User Data Protocol,用户数据报协议)是与 TCP 相对应的协议。它是属于 TCP/IP 协议族中的一种。如图:

 TCP/IP 协议族包括运输层、网络层、链路层,而 socket 所在位置如图,Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层。

四、Socket是什么?

1.Socket起源

socket 起源于 Unix,而 Unix/Linux 基本哲学之一就是 “一切皆文件”,都可以用 “打开 open –>  write/read –> 关闭 close” 模式来操作。Socket 就是该模式的一个实现,        socket 即是一种特殊的文件,一些 socket 函数就是对其进行的操作(读 / 写 IO、打开、关闭).

     说白了 Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Socket 接口后面,对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议。

       注意:其实 socket 也没有层的概念,它只是一个 facade 设计模式的应用,让编程变的更简单。是一个软件抽象层。在网络编程中,我们大量用的都是通过 socket 实现的。

2.套接字描述符

   其实就是一个整数,我们最熟悉的句柄是 0、1、2 三个,0 是标准输入,1 是标准输出,2 是标准错误输出。0、1、2 是整数表示的,对应的 FILE * 结构的表示就是 stdin、stdout、stderr

套接字 API 最初是作为 UNIX 操作系统的一部分而开发的,所以套接字 API 与系统的其他 I/O 设备集成在一起。特别是,当应用程序要为因特网通信而创建一个套接字(socket)时,操作系统就返回一个小整数作为描述符(descriptor)来标识这个套接字。然后,应用程序以该描述符作为传递参数,通过调用函数来完成某种操作(例如通过网络传送数据或接收输入的数据)。

在许多操作系统中,套接字描述符和其他 I/O 描述符是集成在一起的,所以应用程序可以对文件进行套接字 I/O 或 I/O 读 / 写操作。

当应用程序要创建一个套接字时,操作系统就返回一个小整数作为描述符,应用程序则使用这个描述符来引用该套接字需要 I/O 请求的应用程序请求操作系统打开一个文件。操作系统就创建一个文件描述符提供给应用程序访问文件。从应用程序的角度看,文件描述符是一个整数,应用程序可以用它来读写文件。下图显示,操作系统如何把文件描述符实现为一个指针数组,这些指针指向内部数据结构。

 对于每个程序系统都有一张单独的表。精确地讲,系统为每个运行的进程维护一张单独的文件描述符表。当进程打开一个文件时,系统把一个指向此文件内部数据结构的指针写入文件描述符表,并把该表的索引值返回给调用者 。应用程序只需记住这个描述符,并在以后操作该文件时使用它。操作系统把该描述符作为索引访问进程描述符表,通过指针找到保存该文件所有的信息的数据结构。

3. 针对套接字的系统数据结构

(1)套接字 API 里有个函数 socket,它就是用来创建一个套接字。套接字设计的总体思路是,单个系统调用就可以创建任何套接字,因为套接字是相当笼统的。一旦套接字创建后,应用程序还需要调用其他函数来指定具体细节。例如调用 socket 将创建一个新的描述符条目:

(2)虽然套接字的内部数据结构包含很多字段,但是系统创建套接字后,大多数字字段没有填写。应用程序创建套接字后在该套接字可以使用之前,必须调用其他的过程来填充这些字段。

4.文件描述符和文件指针的区别

文件描述符:在 linux 系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在 PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。

文件指针:C 语言中使用文件指针做为 I/O 的句柄。文件指针指向进程用户区中的一个被称为 FILE 结构的数据结构。FILE 结构包括一个缓冲区和一个文件描述符。而文件描述符是文件描述符表的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在 Windows 系统上,文件描述符被称作文件句柄)。

5.基本的 SOCKET 接口函数

在生活中,A 要电话给 B,A 拨号,B 听到电话铃声后提起电话,这时 A 和 B 就建立起了连接,A 和 B 就可以讲话了。等交流结束,挂断电话结束此次交谈。  打电话很简单解释了这工作原理:“open—write/read—close” 模式。

服务器端先初始化 Socket,然后与端口绑定 (bind),对端口进行监听 (listen),调用 accept 阻塞,等待客户端连接。在这时如果有个客户端初始化一个 Socket,然后连接服务器 (connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

五、socket () 函数

int socket(int protofamily, int type, int protocol);//返回sockfd

 sockfd 是描述符。

  socket 函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而 socket () 用于创建一个 socket 描述符(socket descriptor),它唯一标识一个 socket。这个 socket 描述字跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。

      正如可以给 fopen 的传入不同参数值,以打开不同的文件。创建 socket 的时候,也可以指定不同的参数创建不同的 socket 描述符,socket 函数的三个参数分别为:

protofamily:即协议域,又称为协议族(family)。常用的协议族有,AF_INET (IPV4)、AF_INET6 (IPV6)、AF_LOCAL(或称 AF_UNIX,Unix 域 socket)、AF_ROUTE 等等。协议族决定了 socket 的地址类型,在通信中必须采用对应的地址,如 AF_INET 决定了要用 ipv4 地址(32 位的)与端口号(16 位的)的组合、AF_UNIX 决定了要用一个绝对路径名作为地址。

type:指定 socket 类型。常用的 socket 类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET 等等(socket 的类型有哪些?)。

protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC 等,它们分别对应 TCP 传输协议、UDP 传输协议、STCP 传输协议、TIPC 传输协议(这个协议我将会单独开篇讨论!)。

注意:并不是上面的 type 和 protocol 可以随意组合的,如 SOCK_STREAM 不可以跟 IPPROTO_UDP 组合。当 protocol 为 0 时,会自动选择 type 类型对应的默认协议。

当我们调用 socket 创建一个 socket 时,返回的 socket 描述字它存在于协议族(address family,AF_XXX)空间中,但没有一个具体的地址。如果想要给它赋值一个地址,就必须调用 bind () 函数,否则就当调用 connect ()、listen () 时系统会自动随机分配一个端口。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023第十四届蓝桥杯国赛C/C++ 大学 A 组 圆上的连线

思路:很显然总的方案数等于挑选偶数点的方案数乘以对应偶数点的连线方案数之和,挑选偶数点的方案数靠组合数得出,偶数点的连线方案数就是个卡特兰数。具体为什么是卡特兰数,可以任选一个点,枚举这个点所连边的位置&…

Linux搭建sqlilabs靶场

提前准备: 文章中所使用到的Linux系统:Ubantu20.4sqlilabs靶场下载地址:GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based. 一. 安装phpstudy phpstudy安装命令:wget -O install.sh h…

python爬虫实战

import requests import json yesinput(输入页数:) yesint(yes)headers {"accept": "application/json, text/plain, */*","accept-language": "zh-CN,zh;q0.9","content-type": "application/json",…

仿知乎网站问答源码,开源版

仿知乎网站问答源码,开源版 需要一定动手能力 发文章,发视频,发想法,提问回答,注册登录 开发环境 使用技术:springbootthymeleafRedis; 开发环境:tomcat8.0,jdk8.0, ID…

RKNN Toolkit2 工具的使用

RKNN Toolkit2 是由瑞芯微电子 (Rockchip) 开发的一套用于深度学习模型优化和推理的工具。它主要面向在瑞芯微SoC上进行AI应用开发,但也可以用于PC平台进行模型的转换、量化、推理等操作。它支持将多种深度学习框架的模型(如Caffe, TensorFlow, PyTorch等…

如何优雅的分析你的微信朋友圈和聊天记录

微信朋友圈、个人聊天记录、微信群聊天记录: 蓝奏云:链接:​www.lanzoub.com/b00rn0g47e 密码:9hww

SPARC VScode EIDE GDB 使用配置

前言 搞了多年的SPARC 最近接触了VSCODE插件感觉好用。想想看不是能方便调试和编译SPARC,决定使用开源的SPARC仿真环境和编译器来试试。感觉的却不错,借此献给使用SPARC的朋友们。安装 1.找微软官方的下载VSCODE. 2.电机左边的方块形状的图标&#xff0…

周鸿祎成了中国新能源汽车的顶流IP

关注卢松松,会经常给你分享一些我的经验和观点。 以后开公司创业,老板自己做网红是标配。 这句话是我在看了红衣大叔这段时间的操作后发的朋友圈。 短短半年时间(2023.12—2024.5),周鸿祎就从一名传统互联网企业家变成了新能源汽车顶流IP…

C++相关概念和易错语法(10)(定位new、模板)

1.定位new 我们使用类来实例化对象,开辟空间的时候会自动去调用它的构造函数。但在那篇博客我就特意强调过,使用a.A()的方式是错误的,A()根本不会被识别为一个构造函数,而会被识别为A类型。因此我们要注意最好在实例化对象&#…

2024/5/4 英语每日一段

But something is slowing that rocket down: lack of access to the types of data used to train robots so they can interact more smoothly with the physical world.It’s far harder to come by than the data used to train the most advanced AI models like GPT—mos…

08 IRF技术 华三交换机实现

IRF 详细介绍 我知道 AI IRF 技术是指集成路由功能(Integrated Routing and Bridging)技术,是惠普(Hewlett Packard)公司开发的一种基于硬件的虚拟化技术。IRF 技术可以将多台物理设备组合成一个逻辑设备,实现设备的高可用性和灵活性。 IRF 技术主要有以下特点: 1. …

Linux---为什么会有粘滞位?

在前面已经讲过目录的rwx权限: 可读权限(r): 如果目录没有可读权限, 则无法用ls等命令查看目录中的文件内容. 有可写权限(w):如果目录没有可写权限,则无法在目录中创建文件, 也无法在目录中删除文件.可执行权限(x): 如果目录没有可执行权限, 则无法cd到…

五一后返工,3招帮你快速找回状态!

五一假期即将结束,如何快速进入工作状态 随着五一假期的临近结束,我们即将迎来新的工作挑战。在享受了短暂的休息和放松之后,重新调整心态,迅速进入工作状态显得尤为重要。本文将为您提供一些实用的方法和建议,帮助您…

Elasticsearch中【文档查询】DSL语句以及对应的Java实现

目录 全文检索查询 精准查询 布尔查询 排序、分页查询 高亮 地理查询 复合查询 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,一般测…

【业务场景】京东实际场景,频繁GC引起的CPU飙高问题的解决

目录 1.业务介绍 2.判断任务类型 3.CPU飙高的原因 1.业务介绍 本文的业务场景是京东零售线公开的一篇文章,文章内容详细介绍了京东零售线如何将广告相关的定时任务从半小时优化到秒级的,原文链接: 半小时到秒级,京东零售定时…

BUUCTF:Web 解析(一)

前言 Buuctf Web 是一个在线安全挑战平台,旨在提高参与者对网络安全的理解和实践能力。本文将详细介绍 Buuctf Web 的特点、挑战和机遇,帮助读者更好地了解这一领域。 一、Buuctf Web 的特点 多样化的挑战场景:Buuctf Web 提供了多种挑战场…

Redis事务,管道,发布订阅

Redis事务 redis事务本质上是一组命令的集合,按照顺序串行化执行命令而不被其他命令打断 redis事务开启后将要执行的命令放到事务队列中,提交事务后一次性顺序排他地执行所有命令 关键词:单线程,无隔离级别,不保证原子性,排他性,顺序性 要注意和mysql的acid进行区分 怎么用…

【JavaEE】多线程安全问题

文章目录 1、什么是多线程安全问题2、出现线程不安全的原因2.1 线程在系统中是随机调度,抢占式执行的2.2 多个线程同时修改同一个变量2.3 线程针对变量的修改操作,不是“原子”的2.4 内存可见性问题2.5 指令重排序 3 、如何解决线程安全问题3.1 锁操作3.…

2024年3月Scratch图形化编程等级考试(三级)真题试卷

2024年3月Scratch图形化编程等级考试(三级)真题试卷 选择题 第 1 题 Scratch运行程序后,角色一定不会说出的数字是?( ) A.2 B.4 C.6 D.8 第 2 题 Scratch角色初始位置如下图所示,右图…

14_Scala面向对象编程_属性

属性 1.类中属性声明 // 1.给Scala声明属性;var name :String "zhangsan"val age :Int 302.系统默认赋值 scala由于初始化变量必须赋值,为了解决此问题可以采用下划线赋值,表示系统默认赋值 , –但是此方法局限于变量&…