目录
一、网络编程
1.1基础概念
网络编程用途非常的广泛
网络编程主要就是两种网络 --- 局域网 和 广域网
一般情况下局域网指代某一个区域的网络
一般情况下广域网指代可以访问 Internet 的网络
蓝牙、Wifi、Lora、Zigbee 等等都是嵌入式开发中常见的网络
这些网络对应到嵌入式开发都是一个串口
其实对于使用的网络本质上也是局域网 --- 自己的 IP 在当前的网络下有效,而对于广域网,还有一个说法就是 IP 在任何情况下都可以访问 --- 百度
1.2 OSI 七层模型
物理层 → 数据链路层 → 网络层 → 传输层 → 会话层 → 表示层 → 应用层
网络编程:TCP/UDP 协议工作在传输层,而我们的程序属于应用层程序
应用层的主要功能
用户接口:应用层是用户与网络,以及应用程序与网络间的直接接口,使得用户能够与网络进行交互式联系
实现各种服务:该层具有的各种应用程序可以完成和实现用户请求的各种服务
表示层的具体功能
数据格式处理:协商和建立数据交换的格式,解决各应用程序之间在数据格式表示上的差异
数据的编码:处理字符集和数字的转换。例如由于用户程序中的数据类型(整型或实型、有符号或无符号等)、用户标识等都可以有不同的表示方式,因此,在设备之间需要具有在不同字符集或格式之间转换的功能
压缩和解压缩:为了减少数据的传输量,这一层还负责数据的压缩与恢复
数据的加密和解密:可以提高网络的安全性
会话层的具体功能
会话管理:允许用户在两个实体设备之间建立、维持和终止会话,并支持它们之间的数据交换。例如提供单方向会话或双向同时会话,并管理会话中的发送顺序,以及会话所占用时间的长短
会话流量控制:提供会话流量控制和交叉会话功能
寻址:使用远程地址建立会话连接
出错控制:从逻辑上讲会话层主要负责数据交换的建立、保持和终止,但实际的工作却是接收来自传输层的数据,并负责纠正错误。会话控制和远程过程调用均属于这一层的功能。但应注意,此层检查的错误不是通信介质的错误,而是磁盘空间、打印机缺纸等类型的高级错误传输层的主要功能
传输连接管理:提供建立、维护和拆除传输连接的功能。传输层在网络层的基础上为高层提供“面向连接”和“面向无接连”的两种服务。
处理传输差错:提供可靠的“面向连接”和不太可靠的“面向无连接”的数据传输服务、差错控制和流量控制。在提供“面向连接”服务时,通过这一层传输的数据将由目标设备确认,如果在指定的时间内未收到确认信息,数据将被重发。监控服务质量
网络层的主要功能
寻址:数据链路层中使用的物理地址(如 MAC 地址)仅解决网络内部的寻址问题。在不同子网之间通信时,为了识别和找到网络中的设备,每一子网中的设备都会被分配一个唯一的地址。由于各子网使用的物理技术可能不同,因此这个地址应当是逻辑地址(如 IP 地址)
交换:规定不同的信息交换方式。常见的交换技术有:线路交换技术和存储转发技术,后者又包括报文交换技术和分组交换技术
路由算法:当源节点和目的节点之间存在多条路径时,本层可以根据路由算法,通过网络为数据分组选择最佳路径,并将信息从最合适的路径由发送端传送到接收端
连接服务:与数据链路层流量控制不同的是,前者控制的是网络相邻节点间的流量,后者控制的是从源节点到目的节点间的流量。其目的在于防止阻塞,并进行差错检测
数据链路层的主要功能
通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。在计算机网络中由于各种干扰的存在,物理链路是不可靠的。因此,这一层的主要功能是在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法。
该层通常又被分为介质访问控制(MAC)和逻辑链路控制(LLC)两个子层。
MAC 子层的主要任务是解决共享型网络中多用户对信道竞争的问题,完成网络介质的
访问控制;
LLC 子层的主要任务是建立和维护网络连接,执行差错校验、流量控制和链路控制。
数据链路层的具体工作是接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传输。
物理层的主要功能
利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。
“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流说,这个电路是看不见的
对于应用来说,接触不到这种概念的,我们使用的都是系统封装好的接口
1.3 TCP 四/五层模型
1.4 域名
域名是 IP 的“简化” --- 方便人去访问 IP
IP 不好记,但是域名好记
1.5 IP
IP 是设备在网络中的身份证 --- 具有在网络中的唯一性
指的是在当前的网络中
如果在当前网络中出现两个相同的 IP --- IP 冲突 --- 所有人都没有网络
日常生活中接触到的联网设备用的基本上都是局域网
IP 仅仅在当前的网络下有效,直接访问你的 IP 是无法到达的
IP 分类
IPV4 和 IPV6
绝大多数情况下,用的还是 IPV4
IPV4 会将 IP 分类然后用于不同的方向
相当与部分 IP 都给了网站
A 类:0.0.0.0~127.255.255.255
B 类:128.0.0.0~191.255.255.255
C 类:192.0.0.0~223.255.255.255
D 类:224.0.0.0~239.255.255.255
E 类:240.0.0.0~255.255.255.255
1.6 端口
当一个 IP 下有多个设备的时候,端口用于区分 IP 下的不同设备
网络传输中的核心协议
TCP 和 UDP --- 这两个称之为传输层协议
而在开发中用到的网络协议:MQTT --- TCP 的应用层协议
1.7 TCP 协议
面向有链接,稳定,传输速度相对较慢
TCP 协议指的是纯粹的传输层协议,而 TCP/IP 协议包含了部分应用层协议传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。
TCP/IP 传输协议,即传输控制/网络协议,也叫作网络通讯协议。它是在网络的使用中的最基本的通信协议。TCP/IP 传输协议对互联网中各部分进行通信的标准和方法进行了规定。并且,TCP/IP 传输协议是保证网络数据信息及时、完整传输的两个重要的协议。TCP/IP 传输协议严格来说是一个四层的体系结构,应用层、传输层、网络层和数据链路层都包含其中。
TCP 三次握手
确保客户端和服务器正确连接
客户端 → 服务器
SYN = 1,seq = x; --- 客户端给服务器发送同步信号,并且发送一个随机数随机数主要用于判断双方通信是否正确
服务器 → 客户端
ACK = 1,ack = x+1,SYN = 1,seq = y; --- 服务器给客户端回复正确应答,同时回复同步信号,返回一个随机数
客户端 → 服务器
ACK = 1,ack = y+1,SYN = 1。 --- 客户端收到服务器应答信号,和服务器建立连接
TCP 四次挥手
确保数据的完整发送
客户端 → 服务器
FIN = 1,seq = u; --- 客户端告诉服务器,我要断开了
服务器 → 客户端
ACK = 1,ack = u+1,seq = v; --- 服务器收到客户端请求,给客户端回复接受结束请求,然后处理客户端和服务器未完成的数据交互
服务器 → 客户端
FIN = 1,ACK = 1,ack = u+1,seq = w; --- 服务器处理完成和客户端未完成的数据交互,就给客户端发送结束标志
客户端 → 服务器
ACK = 1,ack = v+1,seq = w+1; --- 客户端给服务器回复两次收到的随机数,说明数据连接没有问题
二、TCP 客户端
2.1 介绍
TCP 编程分为客户端和服务器
做的网络编程是局域网 --- 但是只要 IP 换成广域网 IP,编程方法是相同的
TCP 客户端的编程 --- 连接华为云(巴法云),获取时间
在网络编程中,服务器和客户端之间的通信是依靠 --- 通信套接字实现的
对于 TCP 客户端来说,只需要两个函数
socket --- 创建通信套接字
connect --- 连接服务器
2.2 创建通信套接字
头文件
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
函数原型
int socket(int domain, int type, int protocol);
函数参数
domain:IP 的类型
AF_INET --- IPV4
AF_INET6 --- IPV6
type:使用的协议类型
TCP:SOCK_STREAM
UDP:SOCK_DGRAM
protocol:
填 0 即可
函数返回值
成功返回一个大于 0 的通信套接字,失败返回负数
2.3 连接服务器
函数原型
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
函数参数
sockfd:通信套接字
struct sockaddr:
使用的是 struct sockaddr_in,传参需要做一个类型强转
in_port_t sin_port; //端口号
struct in_addr sin_addr;
{
in_addr_t s_addr; //连接服务器的 IP 地址
}
sa_family_t sin_family //IP 协议类型 --- IPV4
存有服务器 IP 和端口号的结构体
addrlen:填结构体的大小
函数返回值
成功返回 0,失败返回负数
在网络中 IP 和端口都是通过大端表示
而计算机都是小端,需要有一个大小端的转换
2.4 IP 的转换
头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数原型
in_addr_t inet_addr(const char *cp)
函数参数
服务器 IP 的字符串
函数返回值
直接赋值给 struct sockaddr_in 结构体下的 struct in_addr sin_addr 成员的
in_addr_t s_addr 成员
2.5 端口的转换
头文件
#include <arpa/inet.h>
函数原型
uint16_t htons(uint16_t hostshort)
函数参数
连接服务器的端口号
函数返回值
直接赋值给 struct sockaddr_in 结构体下的 sin_port 成员