《Linux C/C++ 服务器开发实践》记录

《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协议的分层结构

  1. 应用层 :包含FTP(传输文件),DNS(主机名映射地址),HTTP(获取互联网主页),SMTP(电子邮件收发),TELNET(远程控制)等高级互联网协议。

  2. 传输层:包含TCP(连接,安全可靠)和UDP协议(非连接,快速)服务,用来连接上层应用

  3. 网络层:IP(ICMP,IGMP,ARP,RARP)协议。

  4. 网络接口层(数据链路层):是主机与网络的实际连接层,收发数据帧。

不同的协议层对数据报有不同的称呼,传输层为段(Segment),网络层为报文(或IP数据报),网络接口层为帧。

 

详细的了解各层的工作:

发送方:

  1. 输入网址访问网页,在应用层采用了HTTP协议,浏览器组成HTTP数据发给传输层

  2. 传输层将数据加上TCP首部,标记端口为80(Web服务器默认端口),将这个TCP数据段发给网络层

  3. 网络层在数据段前加上自身ip和目的ip(IP报头),将这个ip数据报发给网络接口层。

  4. 网络接口层在ip数据包前加上自身MAC地址和目的MAC地址,将组成好的帧以比特流的方式发送到网络

接收方:

  1. 网络接口层接受到帧,去掉mac地址,再把ip数据报传给网络层

  2. 网络层去掉IP,将TCP数据段交给传输层

  3. 传输层接受数据段,看到TCP标记的端口为80,说明是HTTP协议,并将数据传给应用层

  4. 应用层看到是HTTP协议的数据,就调用Web服务器程序,发送首页回去。

1.2 应用层

主要协议:

  1. FTP:上网下载文件

  2. HTTP:上网浏览网页

  3. DNS服务:将域名解析为IP地址

  4. 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地址的

工作过程:

  1. 本地主机广播ARP请求,请求中包含目的主机的IP地址。

  2. 目的主机收到请求,用ARP协议解析请求,识别出是询问MAC地址,于是发送ARP应答报,包含IP地址和对应MAC地址

1.4.3 RARP协议

向RARP服务器请求自己的IP地址。

1.4.4 ICMP协议

探测网络是否联通,主机是否可达,路由是否可用,查询诊断网络

ICMP报文可分为两大类别:差错报告报文和查询报文。

1.5 数据链路层

1.5.1 基本概念

传输网络层的数据

解决三个问题:

  1. 如何将数据组合为帧。

  2. 如何控制帧的传输,处理传输差错。如何调节发送速率以使接收方发送方匹配。

  3. 建立数据链路,维持和释放。

1.5.2 主要功能

  1. 为网络层提供服务。

    • 无确定的无连接服务。适用于实时通信要求较高的场景,比如以太网

    • 有确定的无连接服务。适用于误码率较高的场景,比如无线通信

    • 有确认的面向连接服务。适用于通信安全要求较高的场合。

  2. 成帧,帧定界,帧同步,透明传输技术

  3. 差错控制

  4. 流量控制

  5. 链路管理

  6. MAC寻址

2. 搭建Linux开发环境

2.1 准备虚拟机环境

因为我之前学习计算机图形学已经安装过Ubuntu,所以这里略过一些内容。

一些常用的命令或者知识点

  1. 设置root用户密码:

    在终端输入 sudo passwd root,然后输入两次设置的密码。

  2. 拍摄快照:

    可以把当前虚拟机的状态保存下来,以便以后出错了恢复。

3. 多线程基本编程

多线程的编程功力直接决定了服务器性能的优异。

所以提升编程功力能够实打实的提升服务器性能

3.1 使用多线程的好处

  1. 响应速度更灵敏:指的是将单线程的多个任务顺序执行,变为由多个线程共享CPU的时间执行,即使任务未完成也会让出CPU给其他线程,从用户体验看,好像几个任务是同时进行的。就能改善用户体验。

  2. 运行效率更高:让空余的内核被线程占满,运行效率翻好几倍

  3. 通信更高效:同一进程的线程共享该进程的地址空间,可以访问相同的数据,所以线程间的通信效率比进程间的通信效率高

  4. 开销更小:创建线程,切换线程等操作所带来的开销比进程的类似操作的所需开销小得多

    因为线程共享进程资源。创建线程时不再需要分配内存空间等资源。

3.2 多线程编程的基本概念

Windows是支持多进程,多线程的操作系统。

UNIX是支持多进程,单线程的操作系统。

管理线程:POSIX API 函数,C++自带的线程类。

3.2.2 线程的基本概念

每个进程至少有一个线程,CPU执行的是线程,线程是程序的最小执行单位,是操作系统分配CPU时间的最小实体一个进程的所有线程共享进程的公共资源,如虚拟地址空间和全局变量等也可以拥有自己私有的资源

线程在某个进程环境中创建,并在进程退出时被全部销毁。

3.2.3 线程的状态(生命周期)

线程从创建到结束,共有4个状态:

  1. 就绪态

    线程刚被创建,刚从阻塞态恢复,被其他进程抢占,都会导致进入就绪态。处理根据调度策略来把就绪态的线程调度到处理器中运行。

  2. 运行态

  3. 阻塞态

    等待处理器之外的其他条件,无法运行。这里的条件包括I/O操作,互斥锁的释放,条配件变量的改变等。

  4. 终止态

    线程运行已经结束,所占资源未被回收,可以被重新激活,应避免长时间处于该状态,及时进行资源回收。

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使主线程等待。

 

 

posted @   白与花糖  阅读(220)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示