20145337 《信息安全系统设计基础》第十三周学习总结
教材学习内容总结
网络编程
客户端-服务器编程模型
- 一个服务器进程 -> 管理某种资源 -> 经过操做这种资源来为它的客户端提供某种服务
- 一个或多个客户端进程
基本操做:事务
- 当一个客户端须要服务时,向服务器发送一个请求,发起一个事务。
- 服务器收到请求后,解释它,并以适当的方式操做它的资源。
- 服务器给客户端发送一个相应,并等待下一个请求。
- 客户端收到响应并处理它。
- 客户端和服务器都是进程,不是机器或者主机
- 一台主机可同时运行许多不一样客户端服务器,且同一个客户端服务器的事务可在同一台或不一样台主机运行

网络
- 对主机而言,网络是一种I/O设备:从网络上接收到的数据从适配器通过I/O和存储器总线拷贝到存储器,典型地是经过DMA(直接存储器存取方式)传送。
- 物理上,网络是一个按照地理远近组成的层次系统:最低层是LAN(局域网),最流行的局域网技术是以太网。
- 以太网段
- 包括一些电缆和集线器。每根电缆都有相同的最大位带宽,集线器不加分辩地将一个端口上收到的每一个位复制到其余全部的端口上,所以每台主机都能看到每一个位。
- 每一个以太网适配器都有一个全球惟一的48位地址,存储在适配器的非易失性存储器上。
- 一台主机能够发送一段位:帧,到这个网段内其它任何主机。每一个帧包括一些固定数量的头部位(标识此帧的源和目的地址及帧长)和数据位(有效载荷)。每一个主机都能看到这个帧,可是只有目的主机能读取。
- 使用电缆和网桥,多个以太网段能够链接成较大的局域网,称为桥接以太网。这些电缆的带宽能够是不一样的。
- 多个不兼容的局域网能够经过叫作路由器的特殊计算机链接起来,组成一个internet互联网络。
- 互联网重要特性:由采用不一样技术,互不兼容的局域网和广域网组成,并能使其相互通讯。其中不一样网络相互通讯的解决办法是一层运行在每台主机和路由器上的协议软件,消除不一样网络的差别。
- 协议提供的两种基本能力
- 命名机制:惟一的标示一台主机
- 传送机制:定义一种把数据位捆扎成不连续的片的同一方式
互联网络思想的精髓,封装是关键html
全球IP因特网
- TCP/IP协议族
- 混合使用套接字接口函数和UnixI/O函数进行通讯
- TCP提供进程间可靠的、全双工链接。
- 特性:
- 主机集合被映射为一组32位的IP地址
- 这组IP地址被映射为一组称为因特网域名的标识符
- 因特网主机上的进程可以经过链接和任何其余主机上的进程
- 检索并打印一个DNS主机条目:
#include "csapp.h"
int main(int argc, char **argv)
{
char **pp;
struct in_addr addr;
struct hostent *hostp;
if (argc != 2) {
fprintf(stderr, "usage: %s <domain name or dotted-decimal>\n",
argv[0]);
exit(0);
}
if (inet_aton(argv[1], &addr) != 0)
hostp = Gethostbyaddr((const char *)&addr, sizeof(addr), AF_INET);
else
hostp = Gethostbyname(argv[1]);
printf("official hostname: %s\n", hostp->h_name);
for (pp = hostp->h_aliases; *pp != NULL; pp++)
printf("alias: %s\n", *pp);
for (pp = hostp->h_addr_list; *pp != NULL; pp++) {
addr.s_addr = ((struct in_addr *)*pp)->s_addr;
printf("address: %s\n", inet_ntoa(addr));
}
exit(0);
}
套接字接口

Web服务器
- 协议
- Web 客户端和服务器之间的交互用的是一个基于文本的应用级协议,叫作 HTTP (Hypertext Transfer Protocol,超文本传输协议). HTTP 是一个简单的协议。一个 Web 客户端(即浏览器) 打开一个到服务器的因特网链接,而且请求某些内容。服务器响应所请求的内容,而后关闭链接。浏览器读取这些内容,并把它显示在屏幕上。
- 内容
- Web内容能够用一种叫作 HTML(Hypertext Markup Language,超文本标记语言)的语言来编写。一个 HTML 程序(页)包含指令(标记),它们告诉浏览器如何显示这页中的各类文本和图形对象。
- Web 服务器以两种不一样的方式向客户端提供内容:
取一个磁盘文件,并将它的内容返回给客户端。磁盘文件称为静态内容 (static content), 而返回文件给客户端的过程称为服务静态内容 (serving static content)。 运行一个可执行文件,并将它的输出返回给客户端。运行时可执行文件产生的输出称为态内容 (dynamic content),而运行程序并返回它的输出到客户端的过程称为服务动态内容 (serving dynamic content)。程序员
并发编程
-应用级并发
- 访问慢速I/O设备
- 与人交互
- 经过推迟工做以下降延迟
- 服务多个网络客户端
- 在多核机器上进行并行计算
- 进程
- I/O多路复用
线程web
基于进程的并发编程
- 构造并发服务器的天然方法就是,在父进程中接受客户端链接请求,而后建立一个新的子进程来为每一个新客户端提供服务。
- 由于父子进程中的已链接描述符都指向同一个文件表表项,因此父进程关闭它的已链接描述符的拷贝是相当重要的,并且由此引发的存储器泄露将最终消耗尽可用的存储器,使系统崩溃。
- 优势:
- 进程有独立的地址空间
- 缺点:
进程控制和IPC开销高,速度慢编程
基于I/O多路复用的并发编程
- echo服务器必须响应两个相互独立的I/O时间:
- 网络客户端发起链接请求
- 用户在键盘上键入命令行
- I/O多路复用技术的基本思路:使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序。
- 将描述符集合当作是n位位向量:b(n-1),……b1,b0 ,每一个位bk对应于描述符k,当且仅当bk=1,描述符k才代表是描述符集合的一个元素。能够作如下三件事:
- 分配它们;
- 将一个此种类型的变量赋值给另外一个变量;
- 用FDZERO、FDSET、FDCLR和FDISSET宏指令来修改和检查它们。
- echo函数:未来自科幻段的每一行回送回去,直到客户端关闭这个连接。
- 状态机就是一组状态、输入事件和转移,转移就是将状态和输入时间映射到状态,自循环是同一输入和输出状态之间的转移。
- 事件驱动器的设计优势:
- 比基于进程的设计给了程序员更多的对程序行为的控制
- 运行在单一进程上下文中,所以,每一个逻辑流都能访问该进程的所有地址空间,使得流之间共享数据变得很容易。
- 不须要进程上下文切换来调度新的流。
- 缺点:
- 编码复杂
- 不能充分利用多核处理器
粒度:每一个逻辑流每一个时间片执行的指令数量。并发粒度就是读一个完整的文本行所须要的指令数量。浏览器
基于线程的并发编程
- 线程:运行在进程上下文中的逻辑流。
- 线程有本身的线程上下文,包括一个惟一的整数线程ID、栈、栈指针、程序计数器、通用目的寄存器和条件码。全部运行在一个进程里的线程共享该进程的整个虚拟地址空间。
- Posix 线程
- Posix 线程 (Pthreads) 是在 C 程序中处理线程的一个标准接口。Pthreads 定义了大约 60 个函数,容许程序建立、杀死和回收线程,与对等线程安全地共享数据,还能够通知对等线程系统状态的变化。
- 线程的代码和本地数据被封装在一个线程例程(thread routine) 中。若是想传递多个参数给钱程例程,那么你应该将参数放 到一个结构中,并传递一个指向该结构的指针。想要线程例程返回多个参数,你能够返回一个指向一个结构的指针。
- 建立线程
- pthread_create 函数建立一个新的线程,并带着一个输入变量arg,在新线程的上下文中运行线程例程f。能用attr参数来改变新建立线程的默认属性。
- 当 pthreadcreate 返回时,参数 tid包含新建立线程的ID。新线程能够经过调用 pthreadself 函数来得到它本身的线程 ID.
- 终止线程
- 当顶层的线程例程返回时,线程会隐式地终止。 经过调用 pthreadexit 函数,线程会显式地终止。若是主线程调用 pthreadexit , 它会等待全部其余对等线程终止,而后再终止主线程和整个进程,返回值为 thread_return。
- 回收已终止线程的资源
- 线程经过调用 pthread_join 函数等待其余线程终止。
- pthreadjoin 函数会阻塞,直到线程 tid 终止,将线程例程返回的 (void*) 指针赋值为 threadreturn 指向的位置,而后回收己终止线程占用的全部存储器资源。
- pthread join 函数只能等待一个指定的线程终止。
- 分离线程
- 在任何一个时间点上,线程是可结合的 (joinable) 或者是分离的 (detached)。一个可结合的线程可以被其余线程收回其资源和杀死。在被其余线程回收以前,它的存储器资源(例如栈)是没有被释放的。相反,一个分离的线程是不能被其余线程回收或杀死的。它的存储器资源在它终止时由系统自动释放。
- 默认状况下,线程被建立成可结合的。为了不存储器泄漏,每一个可结合线程都应该要么被其余线程显式地收回,要么经过调用 pthread_detach 函数被分离。
- pthreaddetach 函数分离可结合线程 tid. 线程可以经过以 pthreadself()为参数的 pthread_detach 调用来分离它们本身。
- 初始化线程
- pthread_once 函数容许你初始化与线程例程相关的状态。
- 一个基于线程的并发服务器
调用 pthread_ create 时,如何将已链接描述符传递给对等线程。最明显的方法就是传递一个指向这个描述符的指针。 对等线程间接引用这个指针,并将它赋值给一个局部变量。安全
进度图
- 进度图将指令执行模式化为从一种状态到另外一种状态的转换。转换被表示为一条从一点到相邻点的有向边。合法的转换是向右或者向上。
- 临界区:对于线程i,操做共享变量cnt内容的指令构成了一个临界区。
- 互斥的访问:确保每一个线程在执行它的临界区中的指令时,拥有对共享变量的互斥的访问。
- 安全轨迹线:绕开不安全区的轨迹线
- 不安全轨迹线:接触到任何不安全区的轨迹线就叫作不安全轨迹线
任何安全轨迹线都能正确的更新共享计数器。服务器
信号量实现互斥
- 生产者-消费问题
- 读者-写者问题
代码调试中的问题和解决过程
- condvar
消费者等待生产者产产出产品后打印
网络
- count
不加锁的建立两个线程共享同一变量都实现加一操做
并发
- countwithmutex
引入互斥锁
app
- cp_t
用法: ./cp_t [源文件名][目的文件名][建立线程数]

- createthread
打印进程和线程ID

semphore

- share
得到线程的终止状态

threadexit

hello_multi

hello_multi1

hello_single

incprint

- twordcount1
统计文件1和文件2两个文件的总字数

twordcount2

- twordcount3
分别对文件一、2两个文件进行字数统计,并把两个文件的字数加起来统计总字数

twordcount4

分别运行代码根据锁的状况分别统计字数,再把两个文件的字数加起来统计总字数
本周代码托管截图

其余(感悟、思考等,可选)
这周主要学习了网络编程及并发编程的相关知识,自己看着比较复杂,但结合JAVA WEB和操做系统这两门课,就容易理解多了。在JAVA WEB中实现客户端-服务器模型 寥寥几十行代码,只是学到了皮毛,仔细看十一章,才明白其中原理。期末将近,最后几周但愿能补上一些,花更多的时间理解把知识掌握扎实。
学习进度条
目标 |
5000行 |
30篇 |
400小时 |
|
第十三周 |
200/200 |
2/2 |
20/20 |
学习网络编程及并发编程相关知识 |
参考资料