【网络】-- 网络编程套接字(铺垫、预备)
目录
理解源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应用日志的标配; 当然有时候在生产环境中也会考虑和三方中间件采用统一处理方式。日志框架的基础在学习这块时需要一些日志框架的发展和基础,同时了…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...