后台开发
核心技术与应用实践
.
C++ 编程常用技术
最好不要在头文件中使用命名空间, 很容易造成命名冲突.
strlen 与 sizeof 的区别:
strlen 是函数, 在运行时才能计算, 传入参数是 char * 指针, 返回字符串长度.
sizeof()是运算符, 而不是一个函数, 在编译时就计算好了, 用于计算数据空间的字节数.
sizeof 常用于返回类型和静态分配的对象, 结构或数组所占用的空间, 返回值跟内容无关.
在 C++ 中, 临时对象都是 const 类型的.
可以使用 union(联合)判断系统是大端 (big endian) 还是 little endian(小端).
几乎所有网络协议都是采用大端 (big endian) 的方式来传输数据的.
只能把枚举赋值枚举变量, 不能把元素的数值直接赋值枚举变量.
共用体以最长的字节为准, 考虑内存对齐.
结构体以内置类型的最小公倍数对齐.
面向对象的 C++
struct 默认是 public, class 默认的是 private 的.
当一个函数声明为虚函数后, 其派生类中的同名函数都自动成为虚函数.
每个目标文件提供了三个表: 未解决符号表, 导出符号表, 地址重定向表.
未解决符号表提供了多有在编译单元里引用但是定义并不是在本编译单元的符号以及其出现的地址.
导出符号表提供了本编译单元具有定义, 并且愿意提供给其它单元使用的符号及其地址.
地址重定向表提供了本编译单元所有对自身地址的引用的记录.
编译器将 extern 声明的变量置入未解决符号表, extern 是外部链接.
编译器将 static 声明的全局变量不置入未解决符号表, 也不置入导出符号表, 属于内部链接.
编译阶段: g++ 会调用 gcc, 通过 G++ 来完成链接.
Makefile 有 3 个内部变量:
$@ 扩展成当前规则的目标文件名.
$< 扩展成依靠列表中的第一个依靠文件.
$^ 扩展成整个依靠的列表(除了所有重复的文件名).
调试
strace 系统调用:
strace 是通过跟踪系统调用来让开发者直到一个程序在后台所做事情的工具.
strace 首先调用 fork 或 clone 函数新建一个子进程, 然后在子进程中调用 exec 载入需要执行的程序.
gdb 命令参数:
.
内存访问越界的原因:
搜索字符串时, 没有正常的使用结束符.
数组访问越界.
字符串操作函数, 读写越界.
多线程使用了线程不安全的函数.
多线程读写的数据未加锁保护.
非法指针, 包括使用空指针或随意使用指针转换.
堆栈溢出.
TCP 协议
ISO 七层协议:
.
越到底层数据报越大.
TCP 状态图:
.
当出现数据包中途丢失, ACK 报文中途丢失, 对端异常未响应 ACK 或被对段丢弃, TCP 会超时重传.
telnet 和 tcpdump 工具可以用来诊断.
TCP 的滑动窗口主要有两个作用:
一是提供 TCP 的可靠性.
二是体从 TCP 的流量控制特性.
滑动窗口机制还体现了 TCP 面向字节流的设计思路.
任何时候在其发送缓存内的数据都可以分为 4 类:
已经发送并得到对端 ACK;
已经发送但还未收到对端 ACK;
未发送但对端允许发送;
未发送且对端不允许发送.
'已经发送但未收到对端 ACK 的'和'未发送但对端允许发送的'这两部分数据称之为发送窗口.
.
滑动窗口实现面向流的可靠性来源于 "确认重传" 机制.
TCP 的滑动窗口是动态的.
TCP 拥塞控制:
网络中的带宽, 交换结点中的缓存和处理机等, 都是网络的资源.
拥塞控制是防止过多的数据注入网络中, 可以使网络中的路由器或链路不过载.
拥塞控制是一个全局性的过程, 与流量控制不同, 流量控制指点到点的控制.
拥塞控制由 4 个核心算法组成:
慢开始(slow start);
慢开始的思路是一开始不要发送大量的数据, 先探测一下网络的拥塞程度, 由小到大逐渐增加拥塞窗口的大小.
拥塞避免(Congession Voidance);
拥塞避免是让拥塞窗口缓慢增长, 即每经过一个往返时间 RRT 就把发送方的拥塞串口 cwnd 加 1, 而不是加倍.
快速重传(Fast Restransmit);
快速重传要求接收方在收到一个失序报文后就立即发出重复确认, 而不要等到自己发送数据时捎带确认.
发送方连续收到三个重传确认时, 就执行乘法减小算法, 把 ssthresh 门限减半(但是不会执行慢开始).
快速恢复(Fast Recovery).
不执行慢开始, 而是将 cwnd 设置为 ssthresh 的大小, 然后执行拥塞避免算法.
拥塞窗口的大小取决于网络的拥塞成都, 并且动态地变化.
发送方让自己的发送窗口等于拥塞窗口, 考虑接收方的接收能力, 发送串口可能小于拥塞窗口.
TCP 中的 Nagle 算法默认是启用的, 但它并不适合任何情况.
TCP 是个流协议, 就是没有界限的一串数据(没有分界线).
连续调用 send 分别发送两段数据 data1 和 data2:
先接收到 data1, 然后接收到 data2; --- 正常
先接收到 data1 的部分数据, 然后接收到 data1 余下的部分以及 data2 的全部. --- 粘包
接收端接收不及时造成的接收段粘包.
先接收到 data1 的全部数据和 data2 的部分数据, 然后接收到 data2 的余下数据. --- 粘包
nagle 算法等待导致.
两个 send 之间调用 sleep 来休眠一段时间.
一次性接收到了 data1 和 data2 的全部数据. --- 粘包
封包是给数据加上包头.--- 包头给定一个数据包的长度.
nagle 算法等待导致.
循环不停地接收报头给出的数据, 直到收够为止.
在发送内容前, 加上发送内容的长度, 接收方会先接收 4 字节, 解析要接受的长度再进行收包.
一般来说, 一个端口释放后要等待两分钟左右后才能再被使用, 而 SO_REUSEADDR 则可以让端口释放后立即就可以再被使用.
TCP_DEFER_ACCEPT 可以用来预防空连接攻击(只是建立连接, 但是不发送任何数据).
SO_LINGER, linger 是延迟的意思.
SO_RCVBUF 和 SO--SNDBUF 这两个接口选项可以改变默认换从去大小.
网络 I/O 模型
当网络 I/O 发生时, 会设计两个系统对象, 一个是调用这个 IO 的进程, 另一个是系统内核.
当一个 read 操作发生时, 会经历两个阶段:
等待数据准备;
将数据从内核拷贝到进程中.
4 种网络 IO 模型:
阻塞 IO 模型;
阻塞是指 IO 操作需要彻底完成后才返回到用户空间;
.
非阻塞 IO 模型;
非阻塞是指 IO 操作被调用后立即返回给用户一个状态值, 不需要等到 IO 操作彻底完成.
.
多路 IO 复用模型;
事件驱动 IO, 有个函数 (select,poll,epoll) 不断轮询所负责的所有 socket, 当某个 socket 有数据到达了, 就通知用户进程.
.
异步 IO 模型.
异步 IO, 当进程发起 IO 操作之后, 就直接返回, 直到内核发送一个信号, 告诉进程 IO 已完成, 则在这个过程中, 进程完全没有被阻塞.
.
网络分析工具
ping 命令可以检查网络是否连通, 帮助分析和判定网络故障.
ping 发送一个 ICMP(Internet Control Messages Protocol, 因特网信报控制协议), 检查网络是否畅通或者网络连接速度的命令.
tcpdump 根据使用者的定义对网络上的数据包进行截取和分析.
-i, 指定 tcpdump 监听的网络界面.
-c, 指定要监听的数据包数量.
-w, 指定将监听的数据包写入文件保存.
netstat 命令用于显示与 IP, TCP, UDP, IMCP 相关的统计数据, 一般用于检验本机各端口的网络连接情况.
lsof(list open file)是一个列出当前系统打开文件的工具.
Linux 中, 通过文件不仅可以访问数据, 还可以范文网络连接和硬件.
文件描述符为应用程序与基础操作系统之间的交互提供了通用的接口.
lsof | more --- 是一部分一部分地显示.
多线程
多线程就是允许一个进程内存拥有多个控制权, 以便让多个函数同时处于激活 (active) 状态, 从而让多个函数的操作同时运行.
对于多线程来说, 由于同一个进程空间中存在多个栈, 任何一个空白区域被填满都会导致栈溢出.
进程
一般程序转换为进程需要几个步骤:
内核将程序读入内存, 为程序分配内存空间.
内核为该进程分配进程分配标识符 (PID) 和其他所需资源.
内核为进程保存 PID 及相应的状态信息, 把进程放到运行队列中等待执行, 程序转换为进程后就可以被操作系统的调度程序调度执行.
所谓程序就是可运行的二进制文件, 把这种文件加载到内存中运行就二道了一个进程.
同一个程序文件可以被加载多次成为不同的进程.
守护进程:
在 Linux 或者 Unix 操作系统中在系统的引导的时候会开启很多服务, 这些服务叫做守护进程.
守护进程是脱离于终端并且在后台运行的进程.
守护进程是一个生存期较长的进程, 通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.
守护进程通常在系统引导装入的时候启动, 系统关闭时终止.
作业规划进程 crond, 打印进程 lqd(后缀 d 表示 Daemon 的意思).
创建一个守护进程的简单步骤:
创建子进程, 父进程退出.
在子进程中创建新会话(setsid 系统调用, 最重要的一步).
改变当前目录为根目录.
重设置文件权限.
重设文件权限掩码.
关闭文件描述符.
ipcs 命令:
ipcs 命令用于报告系统的消息队列, 信号量, 共享内存等.
HTTP 协议
HTTP(Hypertext Transfer Protocol, 超文本传输协议)是一种详细规定了浏览器和万维网 (world wide web,WWW) 服务器之间互相通信的规则, 通过因特网传送万维网文档的数据传送协议.
HTTP 实在应用层, 基于 TCP 协议, 而 HTTPS 协议, 也是处于应用层, 但是是基于 TLS,SSL 协议层之上的协议.
.
HTTP 默认端口号是 80,HTTPS 默认端口好为 443.
一次 HTTP 操作称为一个事务, 其工作可分为 4 步:
客户机与服务器需要建立连接.
建立连接后, 客户机发送一个请求给服务器, 请求方式的格式为:
统一资源标识符(URL);
协议版本号;
MIME 信息(包括服务器信息, 实体信息和可能的内容).
服务器接到请求后, 给予相应的响应信息, 其格式为一个状态行:
信息的版本协议号;
一个成功或者错误的代码号;
MIME 信息(包括服务器信息, 实体信息和可能的内容).
客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上, 然后客户机与服务器断开连接.
HTTP 永远是客户机发起请求, 服务器惠东响应, 服务器无法将消息推送给客户端.
HTTP 协议结构, 无论是请求报文还是回应报文, 都分为四个部分:
报文头(initial line);
0 个或多个请求头(header line);
空行(作为 header lines 的结束).
HTTP 是基于行的协议, 每一行以 \ r\n 作为分隔符.
wireshark 是一个抓包的好工具, 它能够记录计算机和互联网之间的通信内容.
HTTP 请求方法:
OPTONS: 返回服务器针对特定资源所支持的 HTTP 请求方法; 也可以利用想 Web 服务器发送 "*" 的请求来测试服务器的功能性.
HEAD: 向服务器索要与 GET 请求相一致的响应, 只不过响应体不会被返回.
测试超链接的有效性, 是否可以访问, 以及最近是否更新等信息.
GET: 向特定的资源发出请求, GET 可能会被网络爬虫随意访问.
POST: 向指定资源提交数据进行处理请求(提交表单或者上传文件).
POST 请求可能会导致新的资源的建立或对已有资源的修改.
PUT: 向指定资源位置上传其最新的内容.
DELETE: 请求服务器删除 Request-URI 所标识的资源.
TRACE: 回显服务器收到的请求, 主要用于测试或诊断.
CONNECT: 协议中预留给能够将连接更改为管道方式的代理服务器.
PATCH: 用来将局部修改应用与某以资源.
当某个请求所针对的资源不支持对应的请求方法时, 服务器应当返回状态码 405(Method Not Allowed).
当服务器不认识或者不支持对应的请求方法时, 应当返回状态码 501(Not Implemented).
HTTP 服务器至少要实现 GET 和 HEAD 方法.
HTTPS 协议
公开代码, 算法, 协议, 通过密钥的私密性来保护数据传输的安全性.
对称加密: 加密的密钥和解密的密钥是一样的, 通常使用 AES 和 TEA 算法.
计算量小, 又有一定的破解门槛.
非对称加密: 加密的密钥和解密的密钥是不一样的, 密钥成对出现(公钥加密需要私钥解密, 私钥加密需要公钥解密).
计算量大, 常用 RSA 和 ECC 算法.
一般使用非对称加密算法得出密钥, 再用对称加密算法对消息内容进行加密, 然后进行传输.
HTTP 协议可以轻松抓包并获得其中的内容, 是一个不安全的协议, 而 HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)则是以安全为目标的 HTTP 通道, 可以简单的理解为 HTTP 的安全版.
HTTPS 是一个 URI scheme(抽象标识符体系), 句法类同 HTTP 体系, 用于安全的 HTTP 数据传输.
但 HTTPS 的存在不同于 HTTP 的默认端口及一个加密 / 身份验证层(在 HTTP 与 TCP 之间).
高层的应用协议能透明地建立于 TLS 协议之上.
TLS 协议在应用层之前就已经完成了加密算法, 通信密钥的协商以及服务器的认证工作.
TLS 协议使用通信双方的客户证书以及 CA 根证书, 允许客户端, 服务器端以一种不能被偷听的方式通信, 在通信双方建立起一条安全的, 可信任的通信通道.
HTTP 和 HTTPS 的区别:
HTTPS 协议需要到 CA 申请证书, 一般免费证书很少, 需要交费.
HTTP 是超文本传输协议, 信息是明文传输, HTTPS 则是具有安全性的 ssl 加密传输协议.
HTTP 和 HTTPS 使用的是完全不同的连接方式, 用的端口也不一样, HTTP 使用的是 80 端口号, HTTPS 使用的端口号是 443.
HTTPS 的应用比 HTTP 要少, 因为 HTTPS 比较耗性能, 对于安全性没有那么高要求的应用来说, 用 HTTP 就已经足够了.
CGI
CGI(Common Gateway Interface, 通用网关接口)是 HTTP 协议中最重要的技术之一, 有着不可替代的重要地位.
CGI 是一个 Web 服务器提供信息服务的标准接口.
通过 CGI 接口, Web 服务器就能够获取客户端提交的信息, 转交给服务器段的 CGI 程序进行处理, 最后返回结果给客户端.
CGI 通信系统由两个部分组成:
一部分是 html 页面;
运行在服务器上的 CGI 程序.
.
常用类库
JSON(JavaScript Object Notation, JavaScript 对象表示法)是一种轻量级的数据交换格式, 易于阅读和编写, 同时也易于机器解析和生成.
key-value 对的集合.
值的有序列表.
Protobuf:
Protobuf 的序列化和反序列化的速度更快, 而且传输的数据会先压缩, 使得传输的效率更改些.
Ptotobuf, 全称 Protobuf Buffer, 是 Google 公司内部的混合语言数据标准, 是一种轻便高效的结构化数据存储格式, 可以用于结构化数据串行化(序列化).
适合做数据存储或 RPC 数据交换格式.
来源: https://www.cnblogs.com/longjiang-uestc/p/10869613.html