【Linux取经路】网络套接字编程——初识篇

在这里插入图片描述

文章目录

  • 一、端口号
    • 1.1 认识端口号
    • 1.2 端口号 VS 进程 PID
  • 二、认识 TCP 协议
  • 三、认识 UDP
  • 四、网络字节序列
  • 五、socket 编程接口
    • 5.1 常用 API
    • 5.2 sockaddr 结构
  • 六、结语

一、端口号

网络通信的本质是应用层软件进行数据的发送和接受,软件在启动之后,本质上就是进程,所以网络通信的本质就是进程间通信。网络协议中的下三层,主要解决的是数据安全可靠的送到远端机器。

1.1 认识端口号

  • 端口号是一个2字节16位的整数。

  • 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理。

  • IP 地址 + 端口号能够标识网络上的某一台主机的某一个进程。

  • 一个端口号只能被一个进程占用。

  • 我们把这种基于 IP + 端口号的通信就称作 socket

1.2 端口号 VS 进程 PID

PID 已经可以唯一标识一个进程,为什么还有有端口号的概念?因为并不是所有进程都要进行网络通信,但是所有进程都要有 PID,其次单独设置端口号可以让系统和网络功能进行解耦。但是一个进程可以绑定多个端口号,但是一个端口号只能被一个进程绑定。

image-20240318081741816

每个服务的端口号必须是众所周知的。

二、认识 TCP 协议

  • 传输层协议

  • 有连接

  • 可靠传输(丢包重传、按需到达等,虽然可靠,但是复杂)

  • 面向字节流

三、认识 UDP

  • 传输层协议
  • 无连接
  • 不可靠传输(只要发出去了就不管了)
  • 面向数据报

四、网络字节序列

在内存中的多字节数据相对于内存地址有大端和小端之分,两台进行网络通信的主机,可能发方采用大端,收方采用小端,此时就会出现发方根据大端的规则去发送数据,而收方是按照小端的规则去解释数据的,这样就会导致收方将数据解释出来的意思并不是发方的本意。因此,网络规定:

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。

  • 接收主机把从网络上接到的字节依次保存在接受缓冲区中,也是按照内存地址从低到高的顺序保存。

  • 因此,网络数据流的地址应该这样规定**:先发出的数据是低地址,后发出的数据是高地址**。

  • TCP/IP 协议规定,网络数据流应该采用大端字节序,即低地址高权值位。

  • 不管这台主机是大端机还是小端机,都会按照这个 TCP/IP 规定的网络字节序来发送、接收数据。

  • 如果当前发送主机是小端,就需要先将数据转换成大端;否则就忽略,直接发送即可。

为了使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t hostshort);uint32_t ntohl(uint32_t netlong);uint16_t ntohs(uint16_t netshort);
  • h 表示 host也就是主机,n 表示 network 也就是网络,l 表示 32 位长整数,s 表示 16 位短整数。

  • 例如 htonl 表示将 32 位的长整数从主机字节序列转换为网络字节序列,该接口常用于将 IP 地址转换后准备发送。

  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。

  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

五、socket 编程接口

5.1 常用 API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器) 
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • socket 参数是 socket 函数额返回值,本质上就是一个文件描述符。

5.2 sockaddr 结构

sockt API 是一层抽象的网络编程接口,适用于各种底层网络协议,如 IPv4IPv6,以及 UNIX Domain Socket。然而各种网络协议的地址格式并不一样。套接字编程一共有三种:域间套接字(一个主机内部的进程之间进行通信)、原始套接字(可以跳过传输层,通常用来编写一些网络工具)、网络套接字(用户间的网络通信)。因为套接字编程有三种,所以一般的想法是,设计出三套不同的套接字编程接口,但是这里为了简化,实际上只设计了一套接字编程接口。既然只设计了一套接口,那就要求不管是哪种套接字编程,都只能调用这一种接口,那就要求参数必须要一样。struct sockaddr 就起到这样的作用,它将三种套接字编程的参数类型进行了统一。从下图可以看到,struct sockaddr_in 就是网络套接字的类型,struct sockaddr_un 就是域间套接字的类型,它们的前两字节都存的是套接字类型,所有的套接字编程接口,在内部会去检查类型,然后去执行不同的套接字编程代码。

image-20240318092814581

  • IPv4IPv6 的地址格式定义在 netinet/in.h 中,IPv4 地址用 sockaddr_in 结构体表示,包括 16 位地址类型,16 位端口号和 32 位 IP 地址。

  • IPv4IPv6 地址类型分别定义为常数 AF_INETAF_INET6。这样,只要取得某种 sockaddr 结构体的首地址,不需要知道具体是哪中类型的 sockaddr 结构体,就可以根据地址类型字段确定结构体中的内容。

  • socket API 可以都用 struct sockaddr* 类型表示,在使用的时候需要强制转化成 sockaddr_in;这样做的好处就是程序的通用性,可以接受 IPv4IPv6,以及 UNIX Domain Socket 各种类型的 sockaddr 结构体指针作为参数。

六、结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,春人的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是春人前进的动力!

在这里插入图片描述

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

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

相关文章

spring boot中常用的多线程案例

在Spring Boot中&#xff0c;多线程的应用场景广泛&#xff0c;尤其是在需要提高系统并发处理能力和资源利用率的场景下。以下是一些Spring Boot中常用的多线程案例&#xff0c;并结合参考文章中的相关数字和信息进行说明&#xff1a; 1.异步任务处理 案例描述: 在Spring Bo…

安徽京准 NTP时钟同步服务器具体配置方法是什么?

安徽京准 NTP时钟同步服务器具体配置方法是什么&#xff1f; 安徽京准 NTP时钟同步服务器具体配置方法是什么&#xff1f; 可以使用特权终结点 (PEP) 来更新 Azure Stack Hub 中的时间服务器。 使用可解析为两个或更多个 NTP&#xff08;网络时间协议&#xff09;服务器 IP 地…

网络安全快速入门(十五)(下)手动创建用户及su,sudo命令

15.8 序言 前面我们已经大概了解了创建用户一些相关文件&#xff0c;接下来我们来手动创建用户&#xff0c;话不多说&#xff0c;我们直接开搞&#xff01;&#xff01;&#xff01; 15.9 手动创建用户&#xff1a; 一般来讲&#xff0c;我们创建用户通过useradd和passwd命令来…

Go每日一库之rotatelogs

介绍 Golang的rotatelogs库是一个用于日志轮转&#xff08;log rotation&#xff09;的库。日志轮转是一种常用的日志管理策略&#xff0c;它允许开发者将日志按照一定规则分割成多个文件&#xff0c;以便于管理和分析。通过使用rotatelogs库&#xff0c;开发者可以方便地实现…

python数据分析-心脏衰竭分析与预测

研究背景 人的心脏有四个瓣膜&#xff0c;主动脉银、二尖、肺动脉和三尖源 不管是那一个膜发生了病变&#xff0c;都会导致心脏内的血流受到影响&#xff0c;这就是通常所说的心脏期膜病&#xff0c;很多是需要通过手术的方式进行改善的。随着人口老龄化的加剧,&#xff0c;心…

Java基础_异常

Java基础_异常 异常体系介绍编译时异常和运行时异常异常的作用异常的处理方式JVM默认的处理方式自己处理&#xff08;捕获异常&#xff09;try...catch灵魂四问Throwable的成员方法 抛出处理 综合练习自定义异常来源Gitee地址 异常体系介绍 异常是什么&#xff1f; 程序中可能出…

【Java】String类 -- 重要概念!!!

// 源码 public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];/** Cache the hash code for the string */private int hash; // Default to 0 /…

RTOS笔记--信号量+互斥量+事件组

信号量的本质 信号量是一个特殊的队列&#xff0c;但并不涉及数据传输&#xff0c;因此不需要读写位置和发送者列表&#xff0c;但是多了一个最大计数值。 个人理解&#xff1a;信号量类似一个加入了保护机制的全局变量&#xff0c;不会因为中断切换的原因而导致数据出错。 信号…

Steam游戏如何选择适合的服务器

在Steam平台上&#xff0c;玩家可以享受到来自世界各地开发者的游戏作品。然而&#xff0c;要获得最佳的游戏体验&#xff0c;选择合适的服务器至关重要。本文将从网络延迟、服务器位置、游戏类型和个人偏好等多个方面&#xff0c;为玩家提供选择Steam游戏服务器的实用指南。 如…

k8s挂载配置文件(通过ConfigMap方式)

一、ConfigMap简介 K8s中的ConfigMap是一种用于存储配置数据的API对象&#xff0c;属于Kubernetes中的核心对象。它用于将应用程序的配置信息与容器镜像分离&#xff0c;以便在不重新构建镜像的情况下进行配置的修改和更新。ConfigMap可以存储键值对、文本文件或者以特定格式组…

PDF编辑与修正 提高工作效率 Enfocus PitStop Pro 2022 中文

Enfocus PitStop Pro 2022是一款专为Mac用户设计的强大PDF编辑和校对工具。它支持添加、删除、合并、分割PDF页面&#xff0c;以及文本和图像的编辑&#xff0c;如文字替换、字体更改、颜色调整等。内置自动修复功能&#xff0c;能快速检测并修复缺失字体、重叠文本等常见问题。…

type和interface的继承

type的复用: type Point {x: number;y: number; };type Coordinate Point & {z: number; }; 解释: 这段代码是TypeScript中的类型定义&#xff0c;使用了TypeScript的类型别名&#xff08;type&#xff09;和交叉类型&#xff08;&&#xff09;的特性。 定义Point…

Google Earth Engine(GEE)——使用机器学习进行金三角大米分布图

第 1 步:转到https://code.earthengine.google.com/打开代码编辑器 第 2 步:使用以下代码从 Google Earth Engine Asset 导入数据 // 导入影像集合 var composites = ee.ImageCollection("projects/servir-mekong/yearlyComposites"); // 导入训练数据 var data …

【Text2SQL 论文】PET-SQL:用 Cross-Consistency 的 prompt 增强的两阶段 Text2SQL 框架

论文&#xff1a;PET-SQL: A Prompt-enhanced Two-stage Text-to-SQL Framework with Cross-consistency ⭐⭐⭐ arXiv:2403.09732&#xff0c;商汤 & 北大 Code&#xff1a;GitHub 一、论文速读 论文一开始提出了以往 prompt-based 的 Text2SQL 方法的一些缺点&#xff1…

ug编程怎么录制宏:一步步探索自动化编程的奥秘

ug编程怎么录制宏&#xff1a;一步步探索自动化编程的奥秘 在UG编程的浩瀚领域中&#xff0c;录制宏是一项强大而神秘的功能。它就像一位魔法师&#xff0c;能够将繁琐的重复操作化为简单的指令&#xff0c;释放出惊人的编程效率。然而&#xff0c;对于许多初学者来说&#xf…

使用缓存降低数据库并发读写方案探索

文章目录 前言缓存设计思想缓存划分缓存应用时机 客户端缓存浏览器缓存网关或代理服务器缓存CDNPCDN 服务端缓存本地缓存本地缓存实现Java堆缓存memcached/ecachecaffeineORM框架一级/二级缓存 分布式缓存分布式缓存优缺点分布式缓存实现分布式缓存实施过程可能遇到问题分布式缓…

Linux下svn安装及配置

目录 1、svn安装 2、创建一个仓库目录 3、使用svn自带命令建立仓库 4、编辑svnserve.conf主配置文件 5、编辑passwd文件 6、编辑authz文件 7、启动SVN服务 8、端口开放 9、Linux使用客户端测试 10、在Linux上创建一个文件后提交到SVN 1、svn安装 mount /dev/cdrom /…

Socket编程权威指南(二)完美掌握TCP流式协议及Socket编程的recv()和send()

在上一篇文章中&#xff0c;我们学习了Socket编程的基础知识&#xff0c;包括创建Socket、绑定地址、监听连接、接收连接等操作。然而&#xff0c;真正的套接字编程远不止于此。本文将重点介绍TCP 流式协议&#xff0c;什么是粘包问题&#xff1f;如何解决粘包问题 &#xff1f…

利用R包“Phenotype”对表型值进行检查

首先&#xff0c;你需要确保你已经安装了R和RStudio&#xff08;如果你想用RStudio的话&#xff09;。然后&#xff0c;你可以按照以下步骤进行操作&#xff1a; 加载数据&#xff1a;首先&#xff0c;你需要加载你的表型数据。如果你的数据是以CSV、Excel等格式保存的&#x…

跨网段路由

跨网段路由通常是指在网络中配置路由&#xff0c;以允许不同子网之间的通信。要设置跨网段的永久路由&#xff0c;取决于你是在操作路由器、交换机这样的网络设备&#xff0c;还是在配置个人计算机&#xff08;如Windows或Linux系统&#xff09;。下面是两种常见情况下的简要指…