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.rhkb.cn/news/304118.html

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

相关文章

AMRT3D数字孪生引擎

产品概述 AMRT3D引擎是由眸瑞网络科技自主研发、拥有完全自主知识产权的一款全球首款轻量化3D图形引擎&#xff0c;引擎以核心的轻量化技术及AMRT轻量格式为支柱&#xff0c;专为数字孪生项目开发打造。 AMRT3D引擎提供一整套完善的数字孪生解决方案&#xff0c;在数据处理方…

three.js尝试渲染gbl模型成功!(三)

参照教程&#xff1a;https://cloud.tencent.com/developer/article/2276766?areaSource102001.5&traceId88k805RaN_gYngNdKvALJ &#xff08;作者&#xff1a;九仞山&#xff09; 通过最近两天查three.js入门教程了解到 这玩应支持包括 .obj、.gltf等类型的模型结构。 g…

国产低代码工具,轻松搞定数据迁移

在日常的业务系统升级或者数据维护过程中&#xff0c;数据迁移是各个企业用户不得不面临的问题&#xff0c;尤其是数据迁移过程中要保障数据完整性、统一性和及时性&#xff0c;同时也需要注意源数据中的数据质量问题&#xff0c;比如缺失、无效、错误等问题&#xff0c;需要在…

windows版本-idea中下载的java版本在哪

1、点击idea的file-projectStructure 进入&#xff1a; 通过电脑目录进入该目录 找到bin目录&#xff0c;copy该目录地址 copy下来之后设置到系统环境变量中

synchronized 锁升级过程

synchronized 锁升级过程 Java中的synchronized锁升级过程是JVM为了提高并发性能而引入的一种优化策略&#xff0c;它在JDK 1.6及更高版本中得到了显著的改进。以下是synchronized锁从无锁状态到偏向锁、轻量级锁直至重量级锁的详细升级过程&#xff1a; 无锁状态&#xff1a;…

QT学习day4

widget.h #define WIDGET_H #include <QWidget> #include <QTime>//时间类 #include <QTimerEvent>//定时器类 #include <QPushButton>//按钮类 #include <QTextToSpeech>//语音播报 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_E…

逆向案例十八——webpack逆向红人点集登录密码

网址链接&#xff1a;红人点集 密码登录&#xff0c;获取数据包&#xff1a; 发现pwd和sig两个加密参数&#xff0c;开始跟栈调试 点击第一个&#xff0c;在send处打上断点&#xff0c;再点击登录。 进入异步栈&#xff0c;r.requests 释放之前的断点&#xff0c;打上断点 &a…

【linux】基础IO(四)

在上一篇基础IO中我们主要讲述了文件再磁盘中的存储&#xff0c;当然我们说的也都只是预备知识&#xff0c;为这一篇的文件系统进行铺垫。 目录 搭文件系统的架子&#xff1a;填补细节&#xff1a;inode&#xff1a;datablock[]: 更上层的理解&#xff1a; 搭文件系统的架子&a…

实验1 eNSP安装与使用

实验1 eNSP安装与使用 一、 原理描述二、 实验目的三、 实验内容四、 实验步骤1.下载并安装eNSP2.eNSP软件界面3.搭建并运行网络拓扑4. Wireshark 捕获分组并分析 一、 原理描述 eNSP&#xff08;Enterprise Network Simulation Platform&#xff09;是由华为提供的免费网络模…

【PDF-XSS攻击】Java项目-上传文件-解决PDF文件XSS攻击

文章目录 背景解决pdfbox依赖控制器代码PdfUtils工具类 验证最后源码参考 背景 上传xss-pdf造成存储型xss因为在浏览器直接预览的PDF&#xff0c;而不是预览&#xff0c;所以安全部门认为会有XSS漏洞 解决 安全部门修复建议 1、根据白名单的标签和属性对数据进行过滤&#…

H.265网页无插件播放EasyPlayer.js流媒体播放器常见问题及解答

EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 今天我们来汇总下用户常见的几个问题及解答。 1、EasyPlayer.js播放多路H.265视…

【鸿蒙开发】组件状态管理@Prop,@Link,@Provide,@Consume,@Observed,@ObjectLink

1. Prop 父子单向同步 概述 Prop装饰的变量和父组件建立单向的同步关系&#xff1a; Prop变量允许在本地修改&#xff0c;但修改后的变化不会同步回父组件。当父组件中的数据源更改时&#xff0c;与之相关的Prop装饰的变量都会自动更新。如果子组件已经在本地修改了Prop装饰…

竞赛升温,量子革命待发

人工智能已经吸引了全球企业巨头和政界领袖的广泛关注。同时&#xff0c;一场激烈的全球竞赛正在展开&#xff0c;目标是开发被许多专家视为下一个领域革命性技术的量子计算。 量子计算机利用量子物理学的原理&#xff0c;有潜力推动包括药物研究、股票市场分析以及数据加密在内…

AI论文速读 | TF-LLM:基于大语言模型可解释性的交通预测

论文标题&#xff1a; Explainable Traffic Flow Prediction with Large Language Models 作者&#xff1a;Xusen Guo, Qiming Zhang, Mingxing Peng, Meixin Zhu(朱美新)*, Hao (Frank)Yang(杨昊) 机构&#xff1a;香港科技大学&#xff08;广州&#xff09;&#xff0c;约翰…

【GameFi】链游 | E4C | 堕落竞技场FallenArena

官网&#xff1a;https://www.ambrus.studio/ 游戏下载&#xff1a;https://www.ambrus.studio/game/fallenArena Fallen Arena是一款15人对战游戏&#xff0c;包含单人对战模式和3人队伍对战模式。玩家可以通過收集地图上散落的宝石或消灭对手来获得积分。得分最高的玩家或队伍…

可视化大屏的应用(10):智慧楼宇领域

智慧楼宇可视化大屏可以应用于各种类型的楼宇&#xff0c;包括商业办公楼、住宅小区、医院、学校等。通过可视化大屏&#xff0c;楼宇管理者可以更直观地了解和管理楼宇的运营情况&#xff0c;提高管理效率和用户满意度。 智慧楼宇可视化大屏可以实现以下功能&#xff1a; 能耗…

基于Springboot中小企业设备管理系统设计与实现(论文+源码)_kaic

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…

Redis 的主从复制、哨兵和cluster集群

目录 一. Redis 主从复制 1. 介绍 2. 作用 3. 流程 4. 搭建 Redis 主从复制 安装redis 修改 master 的Redis配置文件 修改 slave 的Redis配置文件 验证主从效果 二. Redis 哨兵模式 1. 介绍 2. 原理 3. 哨兵模式的作用 4. 工作流程 4.1 故障转移机制 4.2 主节…

Redis中的集群(四)

集群 槽指派 CLUSTER ADDSLOTS命令的实现 CLUSTER ADDSLOTS命令接受一个或多个槽作为参数&#xff0c;并将所有输入的槽指派给接收该命令的节点负责: CLUSTER ADDSLOTS <slot> [slot ...]CLUSTER ADDSLOTS命令的实现可以用以下伪代码来表示: def CLUSTER_ADDSLOTS(*…

windows10系统下TP-LINK万兆网卡属性配置高级说明

文章目录 打开配置属性说明ARP Offload&#xff1a;ARP地址解析协议卸载Downshift retries:降档重试次数Energy-Efficient Ethernet:高能效以太网Flow Control:流量控制Interrupt Moderation:中断调整Interrupt Moderation Rate:中断调节率IPv4 Checksum Offload:IPv4校验和卸载…