Linux驱动04 --- 网络编程TCP客户端
目录
一、网络编程
1.1基础概念
1.2 OSI 七层模型
应用层的主要功能
表示层的具体功能
会话层的具体功能
网络层的主要功能
数据链路层的主要功能
物理层的主要功能
1.3 TCP 四/五层模型
1.4 域名
1.5 IP
1.6 端口
1.7 TCP 协议
TCP 三次握手
TCP 四次挥手
二、TCP 客户端
2.1 介绍
2.2 创建通信套接字
2.3 连接服务器
2.4 IP 的转换
2.5 端口的转换
一、网络编程
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 成员