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

社会实践报告
中文摘要: 注重素质教育的今天,社会实践活动一直被视为高校培养德、智、体、美、劳全面发展的跨 世纪优秀人才的重要途径。团期社会实践活动是学校教育向课堂外的一种延伸,也是推进素质教育进程的重 手段。它有助于当代大学生接触社会,了解社…...

LeetCode 460. LFU 缓存 -- 哈希查询+双向链表
LFU 缓存 困难 634 相关企业 请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象 int get(int key) - 如果键 key 存在于缓存中,则获取键…...

Dubbo 源码分析 – SPI 机制
1.简介 SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口 加载实现类。正因此特性࿰…...

JDBC概述二(JDBC编程+案例展示)
一(JDBC的编程步骤) 1.加载数据库驱动 加载数据库驱动通常使用class类的静态方法forName()来实现,具体实现方式如下: Class.forName(“DriverName”),DriverName就是数…...

广度和深度优先搜索解析与示例代码
一,什么是搜索算法 算法是基于特定数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构的。 树是图的一种特例(连通无环的图就是树)。 图上的搜索算法,最直接的理解就是,在图中找出从一个顶点出发,到另一个顶点的路径。具体方法有很多,两种…...
基于SLIC超像素的归一化分割算法
论文:基于SLIC超像素的归一化分割方法研究 归一化分割的缺点:单独使用时无法区分很接近的图像区域,实时性也差。 区域接近问题:描述图像间相互关系的权重函数的取值,体现图像间的信息特征,影响分割效果。…...

C语言刷题(4)——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容又到了我们的复习啦,那么还是刷题噢,话不多说,让我们进入C语言的世界吧 BC55 简单计算器 BC56 线段图案 BC57 正方形图案 BC58 直角三角形图案 BC59 翻转直角三角形图案 BC60 带空格…...

带你看懂RuoYi动态数据源切换
文章目录数据源是什么一、spring中是如何处理各种数据源的?1.开搞springboot2.创建一个测试类二、有了如上的理论,那么想想动态切换数据源吧参考若依的动态数据源配置总结数据源是什么 数据源,对于java来说,就是可用的数据库,那么我平时开发的springboot springclo…...

家有女儿必看:盲目的和青春期女儿较劲,不如掌握4个沟通技巧
导读:家有女儿必看:盲目的和青春期女儿较劲,不如掌握4个沟通技巧 各位点开这篇文章的朋友们,想必都是很高的颜值吧,我们真的是很有缘哦,小编每天都会给大家带来不一样的育儿资讯,如果对小编的文…...

【VC 7/8】vCenter Server 基于文件的备份和还原Ⅰ——基于文件的备份和还原的注意事项和限制
目录1.1 协议1.2 还原后配置说明1.3 Storage DRS1.4 分布式电源管理1.5 分布式虚拟交换机1.6 内容库1.7 虚拟机生命周期操作1.8 vSphere High Availability1.9 基于存储策略的管理1.10 其它注意事项虚拟存储区域网络修补关联博文[图片来源]:https://www.vmignite.co…...