20144303石宇森 《信息安全系统设计基础》第13周学习总结

it2022-05-09  37

20144303石宇森 《信息安全系统设计基础》第13周学习总结

教材内容学习

网络编程

客户端-服务器编程模型

一个应用是由一个服务器进程和一个或多个客户端进程组成服务器进程 -> 管理某种资源 -> 通过操作这种资源来为它的客户端提供某种服务基本操作:事务一个客户端-服务器事务由四步组成:

当一个客户端需要服务时,向服务器发送一个请求,发起一个事务。

服务器收到请求后,解释它,并以适当的方式操作它的资源。

服务器给客户端发送一个相应,并等待下一个请求。

客户端收到响应并处理它。

客户端和服务器都是进程

网络

对主机而言,网络是一种I/O设备:从网络上接收到的数据从适配器经过I/O和存储器总线拷贝到存储器,典型地是通过DMA(直接存储器存取方式)传送。物理上,网络是一个按照地理远近组成的层次系统:最低层是LAN(局域网),最流行的局域网技术是以太网。以太网段包括一些电缆和集线器。每根电缆都有相同的最大位带宽,集线器不加分辩地将一个端口上收到的每个位复制到其他所有的端口上,因此每台主机都能看到每个位。每个以太网适配器都有一个全球唯一的48位地址,存储在适配器的非易失性存储器上。一台主机可以发送一段位:帧,到这个网段内其它任何主机。每个帧包括一些固定数量的头部位(标识此帧的源和目的地址及帧长)和数据位(有效载荷)。每个主机都能看到这个帧,但是只有目的主机能读取。使用电缆和网桥,多个以太网段可以连接成较大的局域网,称为桥接以太网。这些电缆的带宽可以是不同的。多个不兼容的局域网可以通过叫做路由器的特殊计算机连接起来,组成一个internet互联网络。互联网重要特性:由采用不同技术,互不兼容的局域网和广域网组成,并能使其相互通信。其中不同网络相互通信的解决办法是一层运行在每台主机和路由器上的协议软件,消除不同网络的差异。协议提供的两种基本能力

命名机制:唯一的标示一台主机

传送机制:定义一种把数据位捆扎成不连续的片的同一方式

全球IP因特网

TCP/IP协议族因特网的客户端和服务器混合使用套接字接口函数和UnixI/O函数进行通信把因特网看做一个世界范围的主机集合,满足以下特性:

主机集合被映射为一组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); }

套接字接口

函数:

socket函数

connect函数

open_clientfd函数

bind函数

listen函数

open_listenfd函数

accept函数

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多路复用,应用程序在一个进程的上下文中显式的调度控制流。逻辑流被模型化为状态机。

线程,运行在一个单一进程上下文中的逻辑流。由内核进行调度,共享同一个虚拟地址空间。

基于进程的并发编程

构造并发服务器的自然方法就是,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。因为父子进程中的已连接描述符都指向同一个文件表表项,所以父进程关闭它的已连接描述符的拷贝是至关重要的,而且由此引起的存储器泄露将最终消耗尽可用的存储器,使系统崩溃。基于进程的并发echo服务器的重点内容:

需要一个SIGCHLD处理程序,来回收僵死子进程的资源。

父子进程必须关闭各自的connfd拷贝。对父进程尤为重要,以避免存储器泄露。

套接字的文件表表项中的引用计数,直到父子进程的connfd都关闭了,到客户端的连接才会终止。

进程的模型:共享文件表,但不是共享用户地址空间。

关于进程的优劣:

优点:一个进程不可能不小心覆盖两一个进程的虚拟存储器

缺点:独立的地址空间使得进程共享状态信息变得更加困难。进程控制和IPC的开销很高。

Unix IPC是指所有允许进程和同一台主机上其他进程进行通信的技术,包括管道、先进先出(FIFO)、系统V共享存储器,以及系统V信号量。

基于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线程

线程例程:线程的代码和本地数据被封装在一个线程例程中。每一个线程例程都以一个通用指针作为输入,并返回一个通用指针。

创建线程

pthread create函数创建一个新的线程,并带着一个输入变量arg,在新线程的上下文中运行线程例程f。新线程可以通过调用pthread _self函数来获得自己的线程ID。

终止线程

一个线程的终止方式:

当顶层的线程例程返回时,线程会隐式的终止;

通过调用pthread _exit函数,线程会显示地终止。如果主线程调用pthread _exit,它会等待所有其他对等线程终止,然后再终止主线程和整个进程。

回收已终止线程的资源

pthread _join函数会阻塞,直到线程tid终止,回收已终止线程占用的所有存储器资源。pthread _join函数只能等待一个指定的线程终止。

分离线程

在任何一个时间点上,线程是可结合的或者是分离的。一个可结合的线程能够被其他线程收回其资源和杀死;一个可分离的线程是不能被其他线程回收或杀死的。它的存储器资源在它终止时有系统自动释放。默认情况下,线程被创建成可结合的,为了避免存储器漏洞,每个可集合的线程都应该要么被其他进程显式的回收,要么通过调用pthread _detach函数被分离。

初始化线程

pthread _once函数允许初始化与线程例程相关的状态。once _control变量是一个全局或者静态变量,总是被初始化为PTHREAD _ONCE _INIT.

一个基于线程的并发服务器

对等线程的赋值语句和主线程的accept语句之间引入了竞争。

多线程程序中的变量共享

线程存储器模型

每个线程和其他线程一起共享进程上下文的剩余部分。包括整个用户虚拟地址空间,是由只读文本、读/写数据、堆以及所有的共享库代码和数据区域组成的。线程也共享同样的打开文件的集合。任何线程都可以访问共享虚拟存储器的任意位置。寄存器是从不共享的,而虚拟存储器总是共享的。

将变量映射到存储器

全局变量:虚拟存储器的读/写区域只会包含每个全局变量的一个实例。本地自动变量:定义在函数内部但没有static属性的变量。本地静态变量:定义在函数内部并有static属性的变量。

共享变量

变量v是共享的,当且仅当它的一个实例被一个以上的线程引用。

用信号量同步线程

共享变量引入了同步错误的可能性。线程i的循环代码分解为五部分:

Hi:在循环头部的指令块

Li:加载共享变量cnt到寄存器

转载请注明原文地址: https://win8.8miu.com/read-1490358.html

最新回复(0)