《Linux C/C++ 服务器开发实践》记录
序言:该记录是一份读书笔记,因为主题需要和计算机操作系统有关,自然而然的想到Linux的学习,刚好最近找实习发现很多C++服务器方向需要熟悉Windows/Linux的多线程开发,所以就选了这本《Linux C/C++ 服务器开发实践》来看,这本书有许多工作用得上的知识,包括TCP/IP协议簇,Linux环境开发搭建,介绍基本线程进程的概念,多线程开发,基于TCP/UDP的服务器编程以及并发聊天服务器的设计类型等等。其实我还买了另一本Linux书,但是那本书不是入门书,我想要读懂还是有点难度,所以选择这本书来入门Linux。这份笔记记录了本书第1,2,3章的部分内容。使用Markdown语言编写,以博客形式上传到博客园。通过pandoc插件导出为word文档格式,以提供打印版良好的阅读体验。
参考书籍:
朱文伟,李健英.Linux C/C++服务器开发实践[M]. 清华大学出版社,202206.
1. TCP/IP基础
1.1 TCP/IP协议的分层结构
-
应用层 :包含FTP(传输文件),DNS(主机名映射地址),HTTP(获取互联网主页),SMTP(电子邮件收发),TELNET(远程控制)等高级互联网协议。
-
传输层:包含TCP(连接,安全可靠)和UDP协议(非连接,快速)服务,用来连接上层应用。
-
网络层:IP(ICMP,IGMP,ARP,RARP)协议。
-
网络接口层(数据链路层):是主机与网络的实际连接层,收发数据帧。
不同的协议层对数据报有不同的称呼,传输层为段(Segment),网络层为报文(或IP数据报),网络接口层为帧。
详细的了解各层的工作:
发送方:
-
输入网址访问网页,在应用层采用了HTTP协议,浏览器组成HTTP数据发给传输层
-
传输层将数据加上TCP首部,标记端口为80(Web服务器默认端口),将这个TCP数据段发给网络层
-
网络层在数据段前加上自身ip和目的ip(IP报头),将这个ip数据报发给网络接口层。
-
网络接口层在ip数据包前加上自身MAC地址和目的MAC地址,将组成好的帧以比特流的方式发送到网络
接收方:
-
网络接口层接受到帧,去掉mac地址,再把ip数据报传给网络层
-
网络层去掉IP,将TCP数据段交给传输层
-
传输层接受数据段,看到TCP标记的端口为80,说明是HTTP协议,并将数据传给应用层
-
应用层看到是HTTP协议的数据,就调用Web服务器程序,发送首页回去。
1.2 应用层
主要协议:
-
FTP:上网下载文件
-
HTTP:上网浏览网页
-
DNS服务:将域名解析为IP地址
-
SMTP,POP3:收发电子邮件
1.2.1 域名
先查找本地域名服务器;
能解析:返回结果。
不能解析:依次向上查询根服务器的域名,直到能解析为止。
1.2.2 端口
IP地址用来查找通信目标的主机,而端口地址就是用来标记目标程序
如果把IP地址比作旅馆的地址,端口就是某个房间的房号
端口号是16位无符号整数 范围从0到2^16-1,前面1024个端口号留作操作系统使用。
1.3 传输层
TCP协议:一对一,面向连接,对发送的数据报进行排序和确认,并恢复在传输过程中丢失的数据报
UDP协议:一对一或一对多,不可靠的高速通信服务
1.3.1 TCP协议
TCP是面向连接,保证可靠(数据无丢失,无乱序,无错误,无重复到达)的传输层协议。
用C语言定义TCP报头:
typedef struct _TCP_HEADER{
short sSourPort; //源端口号16bit
short sDestPort; //目的端口号16bit
unsigned int uiSequNum; //序列号32bit
unsigned int uiAcknowledgeNum; //确认号32bit
short sHeaderLenAndFlag; //前四位:TCP头长度,中间保留六位,后六为:标志位
short sWindowSize; //窗口大小16bit
short sCheckSum; //检验和16bit
short surgentPointer; //紧急数据偏移量16bit
}TCP_HEADER,*PTCP_HEADER
1.3.2 UDP协议
UDP是无连接,不可靠的传输层协议
用C语言定义UDP报头:
typedef struct _UDP_HEADER{
short m_usSourPort;//源端口号16bit
short m_usDestPort;//目的端口号16bit
short m_usLength; //数据报长度16bit
short m_usCheckSum; //校验和16bit
}UDP_HEADER,*PUDP_HEADER
1.4 网络层
IP协议封装上层数据包后进行传输,若太大可进行分片再传输以适应不同网络环境的需求
1.4.1 IP协议特点
IP协议不可靠,无连接(每个数据报独立进行路线选择到达目的地),无状态(通信双方不清楚数据报的状态信息,如是否乱序和重复)
IP协议在传输数据报时,会把长度超过MTU(物理网络最大传送数据长度)的数据报分片传输,并在母的系统中进行重组
1.4.2 ARP协议
适用于局域网,数据报中只有IP地址,而找到最终目标主机需要MAC地址,ARP协议就是用来将IP地址转化为MAC地址的
工作过程:
-
本地主机广播ARP请求,请求中包含目的主机的IP地址。
-
目的主机收到请求,用ARP协议解析请求,识别出是询问MAC地址,于是发送ARP应答报,包含IP地址和对应MAC地址
1.4.3 RARP协议
向RARP服务器请求自己的IP地址。
1.4.4 ICMP协议
探测网络是否联通,主机是否可达,路由是否可用,查询诊断网络。
ICMP报文可分为两大类别:差错报告报文和查询报文。
1.5 数据链路层
1.5.1 基本概念
传输网络层的数据
解决三个问题:
-
如何将数据组合为帧。
-
如何控制帧的传输,处理传输差错。如何调节发送速率以使接收方发送方匹配。
-
建立数据链路,维持和释放。
1.5.2 主要功能
-
为网络层提供服务。
-
无确定的无连接服务。适用于实时通信要求较高的场景,比如以太网
-
有确定的无连接服务。适用于误码率较高的场景,比如无线通信
-
有确认的面向连接服务。适用于通信安全要求较高的场合。
-
-
成帧,帧定界,帧同步,透明传输技术
-
差错控制
-
流量控制
-
链路管理
-
MAC寻址
2. 搭建Linux开发环境
2.1 准备虚拟机环境
因为我之前学习计算机图形学已经安装过Ubuntu,所以这里略过一些内容。
一些常用的命令或者知识点
-
设置root用户密码:
在终端输入 sudo passwd root,然后输入两次设置的密码。
-
拍摄快照:
可以把当前虚拟机的状态保存下来,以便以后出错了恢复。
3. 多线程基本编程
多线程的编程功力直接决定了服务器性能的优异。
所以提升编程功力能够实打实的提升服务器性能
3.1 使用多线程的好处
-
响应速度更灵敏:指的是将单线程的多个任务顺序执行,变为由多个线程共享CPU的时间执行,即使任务未完成也会让出CPU给其他线程,从用户体验看,好像几个任务是同时进行的。就能改善用户体验。
-
运行效率更高:让空余的内核被线程占满,运行效率翻好几倍
-
通信更高效:同一进程的线程共享该进程的地址空间,可以访问相同的数据,所以线程间的通信效率比进程间的通信效率高。
-
开销更小:创建线程,切换线程等操作所带来的开销比进程的类似操作的所需开销小得多。
因为线程共享进程资源。创建线程时不再需要分配内存空间等资源。
3.2 多线程编程的基本概念
Windows是支持多进程,多线程的操作系统。
UNIX是支持多进程,单线程的操作系统。
管理线程:POSIX API 函数,C++自带的线程类。
3.2.2 线程的基本概念
每个进程至少有一个线程,CPU执行的是线程,线程是程序的最小执行单位,是操作系统分配CPU时间的最小实体。一个进程的所有线程共享进程的公共资源,如虚拟地址空间和全局变量等,也可以拥有自己私有的资源。
线程在某个进程环境中创建,并在进程退出时被全部销毁。
3.2.3 线程的状态(生命周期)
线程从创建到结束,共有4个状态:
-
就绪态
线程刚被创建,刚从阻塞态恢复,被其他进程抢占,都会导致进入就绪态。处理根据调度策略来把就绪态的线程调度到处理器中运行。
-
运行态
-
阻塞态
等待处理器之外的其他条件,无法运行。这里的条件包括I/O操作,互斥锁的释放,条配件变量的改变等。
-
终止态
线程运行已经结束,所占资源未被回收,可以被重新激活,应避免长时间处于该状态,及时进行资源回收。
3.2.4 线程函数
线程函数就是线程创建后进入运行态所要执行的函数。
在创建线程时将定义好的线程函数传给线程创建函数。
线程函数可以是一个全局函数或者时类的静态函数。
3.2.5 线程标识
线程创建成功后返回唯一的ID,从创建开始存在,线程结束后才消失。
3.3 利用POSIX多线程API函数进行多线程开发
API函数 | 含义 |
---|---|
pthread_create | 创建线程 |
pthread_exit | 线程终止自身执行 |
pthread_join | 等待一个线程的结束 |
pthread_self | 获取线程ID |
pthread_cancel | 取消另一个线程 |
pthread_kill | 向线程发送一个信号 |
使用这些API函数需要包含头文件pthread.h,编译的时候需要加上库pthread。表示包含多线程库文件。
为了防止主线程比子线程先一步执行完的情况,需要使用join使主线程等待。
标签:协议,TCP,线程,C++,Linux,服务器,多线程 From: https://www.cnblogs.com/Shiroha-Key/p/17518862.html