【网络】-- 网络编程套接字(铺垫、预备)
目录
理解源IP地址和目的IP地址
认识端口号
端口号
理解源端口号和目的端口号
套接字
认识TCP与UDP协议
网络字节序
socket编程接口
socket 常见API
sockaddr结构
理解源IP地址和目的IP地址
就如同我们唐僧的取经路:
- 唐僧的出发地到目的地:东土大唐 -> 西天。
- 唐僧的长途跋涉途中:东土大唐 -> …… -> 车迟国 -> 黑风岭 -> …… ->西天。
- 源IP -> 目的IP:是永远都不会改变的。
- 源MAC -> 目的MAC:会根据当前所处的位置,不断的进行变化。
目的MAC是受目的IP的影响的,以此到达目地的IP。
认识端口号
我们所使用IPV4,在经过互联网的大爆发,人人拥有上网设备,甚至是几个上网设备,而公司之类的也需要配IP。仅仅IPV4的32位字节,肯定是远远的不够的,而现在之所以还能正常的使用。原因是存在一种技术,叫做NAT技术,其划分了对应的局域网和公网。
而不论是在什么网段,在各自的特定网段当中,IP都要表示该对应主机的唯一性。
#问:把数据送到对方的机器上是目的吗?
不是的,就如同我们在使用一个app的时候,如:抖音,其所播放的视频内容是经过网络申请,然后抖音的服务器将视频内容数据发送给抖音app,那么为什么不是发送给淘宝app偏偏就是要发送给抖音app?就是因为是软件客户端(抖音)申请的数据,然后将数据申请通过给我们的主机,让主机(手机)帮它去申请,所以数据到主机都还是没有结束的。
- 主机(手机):上层的软件客户端在跑。
- 服务器:上层的服务器软件在跑。
所以通讯的时候,并不是两个机器在通讯,而是二者上层的软件在通讯。而对应的软件就是程序员所写的对应的代码,编译所形成的二进制程序。所以准确的来说,因为客户端也是需要打开才哪能申请数据、接收数据。
(对于上面的问题)不是的,真正的网络通信过程,本质上其实是进程间通信!将数据在主机间转发仅仅是手段,(一般在网络通讯的时候真正网络通讯的本质是进程间通讯,但是因为跨主机了,所以我们需要将数据先在主机间进行通讯)机器收到之后,需将数据交付给指定的进程!
#问:将数据教给对应的主机之后,如何保证的主机可以将对应的数据交付给特定的进程?
利用端口号!
端口号
- 端口号是一个2字节16位的整数。
- 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理。
- IP地址 + 端口号能够标识网络上的某一台主机的某一个进程。
- 一个端口号只能被一个进程占用。
端口号是标识特定主机的上的网络进程的唯一性!即:端口号在特定的主机上有若干个进程,端口号不能够被同时绑定,只能够被一个进程进行关联。
所以任何一个发出的报文:一定有IP,port(端口号)。
#问:在Linux的进程中,有一个进程PID,进程PID也标定了进程的唯一性,那进程PID与端口号的关系是什么?
重点是他们标识进程唯一性的能力,进程PID是进程管理的范畴,如果网络也使用进程PID来标识唯一性,那么网络的模块和进程管理的模块就黏在一起了,就会导致两个毫不相关的模块产生关联这是没有任何意义的,单独实现一个端口号提供给网络模块使用,实现网络模块与其他的模块的解耦。
并且不是所有进程都需要端口号,但是是一定所有进程都需要进程PID。
#问:一个进程可以和多个端口号绑定吗?
一个进程可以和多个端口号绑定,我们想绑定几个就绑定几个都没有任何问题。只要一个端口号只能和一个进程关联即可。
理解源端口号和目的端口号
为了让我们进行更好的数据通信,客户端有自己的端口,服务端也有自己的端口。客户端向服务器发送消息,客户端的端口叫做源端口,服务端的端口叫做目的端口。如果是服务端向客户端发数据,客户端的端口叫做目的端口,服务端的端口叫做源端口。
谁发数据谁就是源,谁收数据谁就是目的。
套接字
- SRC_IP:标定互联网中的唯一的一台主机。
- SRC_PORT:标定主机中唯一的进程。
套接字:SRC_IP + SRC_PORT。
网络通讯的本质:进程间通信,套接字编程。
认识TCP与UDP协议
传输层是处于操作系统的,并且是离上层应用层最近的,应用层所使用的接口都是TCP协议 / UDP协议提供的。
认识UDP协议
- 传输层协议
- 无连接 —— 不用写代码的时候刻意连接,直接发送数据
- 不可靠传输 —— 可能会出现网络丢包的问题 / 数据包重复乱序等问题
- 面向数据报
认识TCP协议
- 传输层协议
- 有连接—— 写代码的时候需要刻意连接
- 可靠传输
- 面向字节流
UDP协议就如同发短信,无需经过对方的同意,直接发送即可。TCP协议就如同打电话,需要经过对方的同意,不能直接进行通话,需要对方接听。
#问:为什么UDP协议不可靠,却还是要选择UDP协议?
现在的网络中,出现丢包的问题概率不大,即便出现了丢包问题,有些场景下也是可以容忍的,更重要的是不可靠是特点,可靠也是特点,但是不可靠看起来像缺点,但是它的反面就是没有为了让对应的程序,变得可靠,而做了更多得工作。可靠性是需要付出大量的编码,和数据得处理的,设置更多的策略,更复杂。
TCP协议就是什么都要管,而UDP协议就是只要将数据发出去了就行了。一个更安全,一个更简单。在日常编写中,除非十分的适合UDP协议,其余情况都是使用TCP协议。比如:视频、直播等,在播放的时候出现声音丢失一下、卡一下,就有可能是使用UDP协议,而出现的丢包的情况。
网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分。
什么是大端小端:
大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。
#问:那么如何定义网络数据流的地址呢?
首先,我们需要知道,两天主机如果大小端不一致,经过网络通讯时必然会导致双方无法正常的通信。
解决这个问题,猜测做法:
无论是A -> B发,B -> A发:都把自己的大小端信息特征带上,对方主机提取数据时就先对大小端特征 —— 也很逗,因为大小端特征也是对应的存储,怎么识别?
于是网络就直接规定了:
网络规定:所有的网络数据,都必须是大端!
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存。因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。
- TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。
- 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据。
- 如果当前发送主机是小端,就需要先将数据转成大端。否则就忽略,直接发送即可。
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。
- h:host,n:network,l:32位长整数,s:16位短整数。(h开头代表主机转网络)
- 例如:htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
- 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。
- 如果主机是大端字节序,这些函数不做转换,将参数原封不动。
socket编程接口
socket 常见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 —— 通常用于编写很多很多的工具,一般我们在应用层写代码用的是传输层接口,原始socket允许我们绕过传输层,直接使用网络层,甚至使用网络层以下的底层。
- 网络socket
因为套接字的不同,所以理论上,是三种应用场景,对应的应该是三套接口。但是Linux在设计的时候,不想设计过多的接口,于是就将所有的接口进行了统一。
sockaddr结构
socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIX Domain Socket。然而,各种网络协议的地址格式并不相同。
#:sockaddr结构的出现。
在上述图中,以及前面将常见的三种套接字的介绍,套接字不仅需要支持跨网络的进程间通信,还需要支持本地的进程间通信(域间socket)。在进行跨网络通信时我们需要传递的端口号和IP地址,所以就是必须使用上述的 struct sockaddr_in 结构体。而本地通信(域间socket)则不需要,因此使用上述的 struct sockaddr_un 结构体,其中类型对应的不同,涉及的参数最终导致的是需要两个接口。就是因为 struct sockaddr_in 结构体是用于跨网络通信的,而 struct sockaddr_un 结构体是用于本地通信的,是不同的。
所以,为了让套接字的网络通信和本地通信能够使用同一套函数接口,于是就出现了 struct sockaddr 结构体,该结构体与 struct sockaddr_in 和 struct sockaddr_un 的结构都不相同,但这三个结构体头部的16个比特位都是一样的,叫做地址类型,就是表明其是网络通信的套接字还是本地通信的套接字。
可以说: struct sockaddr 很像一个基类, struct sockaddr_in 和 struct sockaddr_un 是其的派生类。所以我们的传递完全可以传递 struct sockaddr ,最终是什么结构体,完全看完全看结构体头部的16个比特位的对应。
总结:
- IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型,16位端口号和32位IP地址。
- IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。
相关文章:

【网络】-- 网络编程套接字(铺垫、预备)
目录 理解源IP地址和目的IP地址 认识端口号 端口号 理解源端口号和目的端口号 套接字 认识TCP与UDP协议 网络字节序 socket编程接口 socket 常见API sockaddr结构 理解源IP地址和目的IP地址 就如同我们唐僧的取经路: 唐僧的出发地到目的地:东…...
一文打通@SentinelResource
Sentinel 提供了 SentinelResource 注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等 如果使用的是Sentinel Annotation AspectJ Extension,需要导这个依赖 <dependency><groupId>com.alibaba.csp</…...

苹果手机备份的文件在电脑什么地方 苹果备份文件怎么查看
在这个网络信息时代,为手机进行定期备份已经成为了家常便饭。在使用备份软件对苹果手机进行备份后,苹果手机备份的文件在什么地方,苹果备份文件怎么查看呢?本文就带大家来了解一下。 一、苹果手机备份的文件在电脑什么地方 大家…...

【MySQL速通篇001】5000字超详细介绍MySQL部分重要知识点
🍀 写在前面 这篇5000多字博客也花了我几天的时间😂,主要是我对MySQL一部分重要知识点的理解【后面当然还会写博客补充噻,欢迎关注我哟】,当然这篇文章可能也会有不恰当的地方【毕竟也写了这么多字,错别字可…...

并发编程——synchronized优化原理
如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:耶瞳空间 一:基本概念 使用synchronized实现线程同步,即加锁,实现的是悲观锁。加锁可以使一段代码在同一时间只有一个线程可以访问,在增加安全性的同…...
LeetCode 剑指 Offer II 083. 没有重复元素集合的全排列
给定一个不含重复数字的整数数组 nums ,返回其 所有可能的全排列 。可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 1 < nums.length < 6 -10 < nu…...
JSONObject与JSONArray使用区别
目录 1.使用的场景区别 2. 使用方法区别 3.获取方式不同 4. 解析JSON字符串 5.总结 1.使用的场景区别 想通过键值对的形式获取数据,使用JSONObject。如果后台查询的是某个bean的list集合向前端页面传递,使用JSONArray。 2. 使用方法区别 创建方法不…...
经典C程序例程:通过进程ID得到文件名
通过进程ID得到文件名 #include <stdio.h> #include <windows.h> #include <tlhelp32.h> #include <tchar.h>BOOL EnablePrivilege(HANDLE hToken,LPCSTR szPrivName); void DispProcess(void); void DispPrsFile(void);// typedef BOOL (_stdcall *E…...

【Java】Spring MVC程序开发
文章目录Spring MVC程序开发1. 什么是Spring MVC?1.1 MVC定义1.2 MVC 和 Spring MVC 的关系2. 为什么学习Spring MVC?3. 怎么学习Spring MVC?3.1 Spring MVC的创建和连接3.1.1 创建Spring MVC项目3.1.2 RequestMapping 注解介绍3.1.3 Request…...
leetcode题解-704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出: 4 解释: 9 出现…...
2.2 C语言程序的错误条件
在C语言程序中,条件语句决定程序的执行路径,因此条件表达式是程序的关键。 应用最经典的程序,除法的减法实现程序,解释条件表达式的重要性。x=y*q+r,x是被除数,y是除数,q是商,r是余数。 程序的方法, x=(r-y)+y*(1+q)。 main(){ /*错误条件的程序*/ r:=x; q:=0; whil…...

laravel 邮件发送
配置 Laravel 的邮件服务可以通过 config/mail.php 配置文件进行配置。 邮件中的每一项都在配置文件中有单独的配置项,甚至是独有的「传输方式」,允许你的应用使用不同的邮件服务发送邮件 mailers > [smtp > [transport > smtp,host > env(M…...
高性能 Jsonpath 框架,Snack3 3.2.57 发布
Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计。其下一切数据都以ONode表示,ONode也即 One node 之意,代表任何类型,也可以转换为任何类型。 强调文档…...

Android---进程间通信机制3
1 服务如何注册到 SM 中 getIServiceManager().addService(name, service, false); getIServiceManger --- new ServiceManagerProxy(new BinderProxy()) BinderInternal.getContextObject --- 返回 BinderProxy 对象 ProcessState::self()->getContextObject: 创建一个 BpB…...

Python实战,爬取金融期货数据
大家好,我是毕加锁。 今天给大家带来的是 Python实战,爬取金融期货数据 文末送书! 文末送书! 文末送书! 任务简介 首先,客户原需求是获取https://hq.smm.cn/copper网站上的价格数据(注:获取的是…...

Allegro如何导入第三方网表操作指导
Allegro如何导入第三方网表操作指导 在用Allegro做PCB设计的时候,除了支持第一方网表的导入,同样也是可以导入第三方网表的,第三方网表如下图 如何导入,具体操作如下 点击Setup点击User Preference...

高码率QPSK调制解调方案(FPGA实现篇)
在前面的章节中,已经讲过QPSK调制的方案和Matlab算法仿真,在本篇中,主要讲解基于FPGA的高速QPSK调制的实现。根据前面提到的技术指标,本系统传输的数据速率为500Mbps,中频为720MHz,因此,传统的串行QPSK调制已经不合适在FPGA中实现,需采用全数字的并行方式进行调制,具体…...
Elasticsearch的RESTful Api使用
Elasticsearch的RESTful Api使用 文章目录Elasticsearch的RESTful Api使用查询集群健康情况查看所有索引其他的_cat命令创建索引删除索引修改索引查看索引创建文档批量操作文档删除文档查询文档全量更新文档局部更新文档索引的搜索分词分析分数说明查询类型分析查询集群健康情况…...
软著申请需要注意的
一、文档格式 (1)程序源代码和说明文档,源码前后30页,文档前后30页。 (2)软件源代码和说明书的页眉必须标明软件名称、版本号和页码,应当与申请表中相应内容完全一致 (3)…...
SpringBoot入门 - 添加Logback日志
SpringBoot开发中如何选用日志框架呢? 出于性能等原因,Logback 目前是springboot应用日志的标配; 当然有时候在生产环境中也会考虑和三方中间件采用统一处理方式。日志框架的基础在学习这块时需要一些日志框架的发展和基础,同时了…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...