Linux网络基础 (三) —— Socket

文章目录

  • Socket 编程
    • 基本概念
      • Socket背景
      • Socket 为了解决什么问题
    • socket
    • sockaddr结构
      • sockaddr
      • sockaddr_in
      • sockaddr 和 sockaddr_in 的关系
      • sockaddr_un
    • 示例代码

🎖  博主的CSDN主页:Ryan.Alaskan Malamute
📜 博主的代码仓库主页 [ Gitee ]:@ryanala      [GitHub]: Ryan-Ala

Socket 编程

基本概念

Socket背景

  Socket(套接字)是一种用于实现网络通信的编程接口(API),它提供了一种标准化的方式,使得不同操作系统和编程语言之间的应用程序能够相互通信。Socket最初是在BSD(Berkeley Software Distribution)操作系统中开发出来的,目的是为了实现在不同主机之间进行进程间通信。BSD是由加州大学伯克利分校开发的一个Unix操作系统的分支,它对Socket的定义和实现成为了事实上的标准。后来,由于互联网的发展,Socket被广泛应用于网络编程中。

  在早期的计算机网络中,通信使用的是不同的协议,这些协议之间缺乏标准化的接口,使得应用程序的编写和移植变得非常困难。为了解决这个问题,一些计算机科学家开始研究如何定义一种标准的通信接口,以便不同的计算机之间能够进行通信。Socket就是在这个背景下诞生的,它提供了一种可移植、可扩展、易于使用的接口,使得应用程序能够在不同的操作系统和计算机之间进行通信。

  随着互联网的发展,Socket成为了网络编程中不可或缺的一部分。它被广泛应用于各种网络应用程序中,如Web服务器、电子邮件客户端、聊天程序等。同时,随着计算机硬件和网络技术的不断发展,Socket也不断更新和完善,以适应新的应用场景和需求。

Socket 为了解决什么问题

  Socket通信主要是为了解决计算机网络中的进程间通信问题。在网络编程中,有两个进程需要进行通信才能完成特定的任务,这两个进程可能运行在不同的计算机上,也可能运行在同一台计算机上的不同进程中。Socket提供了一种标准化的接口,使得这些进程能够在网络中进行数据交换和通信。具体来说,Socket通信可以解决以下几个方面的问题:

  1. 进程间通信:在同一台计算机上,不同的进程之间需要进行通信,Socket提供了一种标准化的接口,使得进程之间可以通过网络进行通信。
  2. 跨平台通信:不同的计算机、操作系统和编程语言之间需要进行通信,Socket提供了一种可移植的接口,使得应用程序可以在不同的平台上运行并进行通信。
  3. 网络通信安全性:网络通信中存在着信息泄露、数据篡改、拒绝服务攻击等安全问题,Socket可以通过加密、身份认证、防火墙等方式提高通信的安全性。
  4. 通信协议:Socket提供了一种灵活的通信协议,可以根据需要选择不同的协议来满足特定的通信需求,如TCP、UDP等协议。

总之,Socket通信可以为应用程序提供一种标准化、可靠、安全的网络通信方式,使得不同计算机之间的应用程序可以进行数据交换、信息共享和远程控制等操作。

简单来说

  • socket编程也叫套接字编程,应用程序可以通过它发送或者接受数据,可对其像打开文件一样打开、关闭、读写等操作.
  • 套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信.
  • 网络套接字是IP地址与端口号TCP协议的组合
  • Socket就是为网络编程提供的一种机制,通信的两端都有Socket
  • 网络通信其实就是Socket之间的通信,数据在两个Socket之间通过I/O进行传输.

socket

Socket 编程需要包含如下头文件

#include<sys/types.h>
#include<sys/socket.h>

函数原型:

int socket(int domain, int type, int protocol);       // 2:46:00
//创建套接字就可以理解为创建了struct file对象其中包含了很多文件指针
// 该函数返回一个文件指针,套接字文件描述符,即代表socket函数创建的套接字文件// 使用示例:_sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个网络通信的文件
if (_sockfd < 0)
{// 如果错误,就打印日志lg.LogMessage(Fatal, "socket error, %d : %s \n", errno, strerror(errno));exit(Socket_Err);
}
  • domain

    常用的三种阈

    名称含义
    AF_UNIX用于本地进程间的通信
    AF_INET,PF_INETIPv4 Internet协议
    PF_INET6IPv6 Internet协议
    1. AF:表示ADDRESS FAMILY 地址族

      地址族就是一个协议族所使用的地址集合,也是用宏来表示不同的地址族,这个宏的形式是AF开头,比如IP地址族为AF_INET,

    2. PF:表示PROTOCOL FAMILY 协议族

      协议族就是不同协议的集合,在Linux中,用宏来表示不同的协议族,这个宏的形式是PF开头,比如IPv4协议族为PF_INET

    3. 区别:

      地址族和协议族其实是一样的,值也一样,都是用来识别不同协议的,为什么要搞两套东西呢?

      ​ 这是因为之前UNIX有两种风格系统:BSD系统POSIX系统

      • 对于BSD系统,一直用的是AF
      • 对于POSIX系统,一直用的是PF

      Linux作为后起之秀,为了兼容,所以两种都支持,这样两种风格的UNIX下的软件就可以在Linux上运行了。

  • type

    type用于设置套接字通信的类型,主要有SOCKET_STREAM(流式套接字)、SOCK_DGRAM(数据包套接字)

    名称含义
    SOCK_STREAMTcp 连接,提供序列化的、可靠的、双向连接的字节流。支持带外数据传输
    SOCK_DGRAMUDP 连接(无连接状态的消息)
    SOCK_SEQPACKET序列化包,提供一个序列化的、可靠的、双向的基本连接的数据传输通道,数据长度定常。每次调用读系统调用时数据需要将全部数据读出
    SOCK_RAWRAW类型,提供原始网络协议访问
    SOCK_RDM提供可靠的数据报文,不过可能数据会有乱序
    SOCK_PACKET这是一个专用类型,不能呢过在通用程序中使用
  • protocol

    1. protocol用于制定某个协议的特定类型,即type类型中的某个类型。通常某协议中只有一种特定类型,这样protocol参数仅能设置为0

    2. 但是有些协议有多种特定的类型,就需要设置这个参数来选择特定的类型。

  • errno

    函数socket()并不总是执行成功,有可能会出现错误,错误的产生有多种原因,可以通过errno获得

    含义
    EACCES没有权限建立制定的domain的type的socket
    EAFNOSUPPORT不支持所给的地址类型
    EINVAL不支持此协议或者协议不可用
    EMFILE进程文件表溢出
    ENFILE已经达到系统允许打开的文件数量,打开文件过多
    ENOBUFS/ENOMEM内存不足。socket只有到资源足够或者有进程释放内存
    EPROTONOSUPPORT制定的协议type在domain中不存在

sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIX Domain Socket. 然而, 各种网络协议的地址格式并不相同.

sockaddr

在写代码前,需要先了解这三个结构间的关系,sockaddr结构体在如下头文件中定义

#include <sys/socket.h>

sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了

sockaddr 可以强转为 sockaddr_insockaddr_un,( 类似于父类子类的感觉 )

struct sockaddr 
{  sa_family_t sin_family;   //地址族char sa_data[14];         //14字节,包含套接字中的目标地址和端口信息               
};

  • IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16位端口号和32位IP地址.
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
  • socket API可以都用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;

sockaddr_in

头文件

#include<netinet/in.h>
#include<arpa/inet.h>

此结构的地址类型为AF_INET,是网络套接字

  • sockaddr_in结构体是和sockaddr结构并列且等价的结构体,因此它们二者之间可以互相转化,也是真正用来提供给程序员进行填充操作的结构体

  • 区别在于 sockaddr_insa_data 划分为 sin_portsin_addr,也就是把端口和IP地址信息区分开,sin_port采用了网络字节序,同时为了保持和sockaddr相同的字节大小,填充了8字节的sin_zero。这也是一个只针对IPv4地址的结构体,因此它的 sin_family 只能是 AF_INET

//简略版
struct sockaddr_in
{__SOCKADDR_COMMON(sin_);  //该项是个宏,在编译时会将 sin_ 和 family 拼接后形成成员     sin_famliyin_port_t sin_port;struct in_addr sin_addr
}//详细版
struct sockaddr_in
{__SOCKADDR_COMMON (sin_);   // 此成员就是 sin_family , __SOCKADDR_COMMON 是一个宏,编译后 sin_ 后面会接上 family in_port_t sin_port;	  /* Port number.  */       // uint16_t 类型   16 位 TCP/UDP 端口号struct in_addr sin_addr;    /* Internet address.  */    //32 位 IP 地址/* Pad to size of `struct sockaddr'.  */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];
};//  in_addr 的类型    (32位IP地址)
typedef uint32_t in_addr_t;
struct in_addr
{in_addr_t s_addr;    //  32 位 IPv4 地址
};

在这里插入图片描述

使用示例:

注意,该结构体使用先进行置空

 struct sockaddr_in local;bzero(&local, sizeof(local)); // 将指定的内存清零
local.sin_family = AF_INET;   // 告诉系统绑定的是网路通信的信息local.sin_port = htons(_port); // _port 是主机序列,需要主机转网络序列local.sin_addr.s_addr = inet_addr(_ip.c_str()); // sin.adder 是一个结构体,这个结构体里面只有一个成员//  1. 将 _ip变为四字节ip  2. 变成网络序列

sockaddr 和 sockaddr_in 的关系

  • 二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。

  • sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。

  • sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。

sockaddr_un

头文件

#include<netinet/in.h>
#include<arpa/inet.h>

sockaddr_un是一种UNIX套接字,通常在使用这种方式时不用网络套接字,而是用本地套接字

struct sockaddr_un
{uint16_t sun_family;char sun_path[108]; /* Path name. */
};
  • 通讯类型只能选择 SOCK_STREAM 和 SOCK_DGRAM,协议为默认协议
  • sun_family 参数只能选择AF_LOCAL和AF_UNIX
  • sun_path 参数为本地文件路径,通常放在 /temp 目录下

示例代码

这是UDP网络程序编写的极小部分代码,用到了 socket 函数和 sockaddr_in 结构体,在后续文章完整编写 UdpServer 服务器时还会用到,这里先放出部分用于了解 如何使用 socket 和 sockaddr_in

// 创建网络套接字文件
_sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个 使用IPV4 UDP链接 的网络套接字// 指定网络信息
struct sockaddr_in local;
bzero((void *)&local, (size_t)sizeof local);local.sin_family = AF_INET;
local.sin_port = htons(_port);  // 将端口号从主机字节序转换为网络字节序
local.sin_addr.s_addr = inet_addr(default_ip.c_str()); // 将 string 的 ip 信息 转换为网络字节序

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

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

相关文章

【MySQL】数据操作语句(DML)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习计网、mysql和算法 ✈️专栏&#xff1a;MySQL学习 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…

【论文通读】AgentStudio: A Toolkit for Building General Virtual Agents

AgentStudio: A Toolkit for Building General Virtual Agents 前言AbstractMotivationFramework评估GUI GroudingReal-World Cross-Application Benchmark Suite Conclusion 前言 来自昆仑万象的一篇智能体环境数据大一统框架工作&#xff0c;对未来计算机智能体的发展具有指…

FPGA常用IP核之FIFO学习

IP核是FPGA芯片公司提供的逻辑功能块&#xff0c;在FPGA芯片中可以进行优化和预先配置&#xff0c;可以直接在用户设计的程序中使用&#xff0c;应用范围很广。在FPGA设计开发过程中使用IP核&#xff0c;可以大大的缩短开发周期&#xff0c;高度优化的IP核可以使FPG开发工程师专…

前端三剑客 —— CSS (第六节)

目录 内容回顾&#xff1a; 弹性布局属性介绍 案例演示 商品案例 布局分析 登录案例 网格布局 内容回顾&#xff1a; 变量&#xff1a;定义变量使用 --名称&#xff1a;值&#xff1b; 使用变量&#xff1a; 属性名&#xff1a;var&#xff08;--名称&#xff09;&a…

虚拟主机、VPS主机和云服务器的区别

对于每个建站新手来说&#xff0c;首先要解决的就是服务器购买的问题&#xff0c;目前市面有很多类型的服务器&#xff0c;常见的有&#xff1a;阿里云、腾讯云、Vultr云服务器&#xff0c;也有RackNerd、Cloudways等提供的VPS&#xff0c;还有SiteGround、ChemiCloud 、 Hosti…

数据结构之堆底层实现的循序渐进

题外话 把没写的都补回来! 正题 堆 概念 堆是一棵完全二叉树&#xff0c;因此可以层序的规则采用顺序的方式来高效存储&#xff0c; 大根堆:指根结点比左右孩子都大的堆 小根堆:指根结点比左右孩子都小的堆 性质 1.堆中某个节点的值总是不大于或不小于其父节点的值 2…

鸿蒙OS元服务开发:【(Stage模型)设置应用主窗口】

一、设置应用主窗口说明 在Stage模型下&#xff0c;应用主窗口由UIAbility创建并维护生命周期。在UIAbility的onWindowStageCreate回调中&#xff0c;通过WindowStage获取应用主窗口&#xff0c;即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性&…

每日一题(leetcode1026):节点与其祖先的最大差值--dfs

考虑到只能计算祖先之间的节点差而不能计算兄弟之间的节点差&#xff0c;所以思考使用dfs来解决该题。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), ri…

嵌入式开发学习---(部分)数据结构(无代码)

数据结构 为什么学习数据结构&#xff1f; 1&#xff09;c语言告诉如何写程序&#xff0c;数据结构是如何简洁高效的写程序 2&#xff09;遇到一个实际问题&#xff0c;需要写程序去实现相应功能&#xff0c;需要解决那两个方面的问题&#xff1f; 如何表达数据之间的逻辑规律…

背包问题---

一、背包模型 有一个体积为V的背包,商店有n个物品,每个物品有一个价值v和体积w,每个物品只能被拿一次,问能够装下物品的最大价值。 这里每一种物品只有两种状态即"拿"或"不拿". 设状态dp[i][j]表示到第i个物品为止,拿的物品总体积为j的情况下的最大价…

一、持续集成介绍

持续集成介绍 一、什么是持续集成二、持续集成的流程三、持续集成的组成要素四、持续集成的好处 一、什么是持续集成 持续集成&#xff08;CI&#xff09;指的是&#xff0c;频繁地&#xff08;一天多次&#xff09;将代码集成到主干。持续集成的目的&#xff0c;就是让产品可…

LeetCode:1483. 树节点的第 K 个祖先(倍增 Java)

目录 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 实现代码与解析&#xff1a; 倍增 原理思路&#xff1a; 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#…

软件测试——黑盒测试

黑盒测试也就是针对功能进行测试&#xff0c;白盒测试就是后端根据自己的代码逻辑进行一下自测&#xff0c;灰盒测试就是黑盒和白盒的混合测试。 1.黑盒测试主要发现以下类型的错误 对比需求规格说明书功能遗漏或者不一致。 接口错误 数据库连接访问错误 效率不高&#xff…

【好书推荐-第十四期】《 互联网大厂晋升指南:从P5到P9的升级攻略》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号&#xff1a;洲与AI。 &#x1f388; 本文专栏&#xff1a;本文收录…

第八讲 Sort Aggregate 算法

我们现在将讨论如何使用迄今为止讨论过的 DBMS 组件来执行查询。 1 查询计划【Query Plan】 我们首先来看当一个查询【Query】被解析【Parsed】后会发生什么&#xff1f; 当 SQL 查询被提供给数据库执行引擎&#xff0c;它将通过语法解析器进行检查&#xff0c;然后它会被转换…

机器人力觉控制(力源)原理及力矩传感器性能分析

机器人力控原理及其性能分析 在机器人的操作任务中&#xff0c;处理机器人和环境之间的物理接触是非常重要的。由于机器人系统的复杂性和不确定性&#xff0c;纯运动控制往往是不够的&#xff0c;因为即使是最精确的模型也无法完全准确地预测所有可能的情况。 当机器人在与环境…

arm开发板移植工具mkfs.ext4

文章目录 一、前言二、手动安装e2fsprogs1、下载源码包2、解压源码3、配置4、编译5、安装 三、移植四、验证五、总结 一、前言 在buildroot菜单中&#xff0c;可以通过勾选e2fsprogs工具来安装mkfs.ext4工具&#xff1a; Target packages -> Filesystem and flash utilit…

vue3中mars3d通过滑动条去改变地图图层的透明度

效果图 加滑动条 因为我这个存在单选框&#xff0c;在点击滑动条的时候 会出现将单选框选中的问题&#xff0c;所以用了一个div把滑动条包裹起来并加了冒泡 changeLiveSituationBg方法 // 改变底图显示颜色 val是我点击这个单选框对应值 const changeLiveSituationBg va…

5G智慧地铁数字孪生可视化平台,推进铁路行业数字化转型

随着科技的快速发展&#xff0c;5G智慧地铁数字孪生可视化平台正逐渐成为铁路行业数字化转型的重要推动力。巨蟹数科数字孪生平台集成了5G通信技术、大数据分析、云计算和人工智能等先进技术&#xff0c;通过构建数字孪生模型&#xff0c;实现对地铁运营全过程的实时监控、预测…

互联网大厂都在用的DevOps工具,看看你会几样?

关注公众号&#xff1a;“DevOps实战派”&#xff0c;获取更多DevOps和运维的精彩内容。 DevOps 是一种强调开发与 IT 运营之间合作的软件开发范式&#xff0c;主要依靠自动化来优化流程、提高生产力并确保及时、可靠的软件交付。 下面&#xff0c;我将介绍目前在互联网大厂中…