2017-2018-1 20155302 《信息安全系统设计基础》第8周学习总结

2017-2018-1 20155302 《信息安全系统设计基础》第8周学习总结

第十一章教材学习内容总结

客户端-服务器编程模型

1.每个网络应用都是基于客户端-服务器模型的。采用这个模型,一个应用是由一个服务器户端提供某种服务。服务器管理某种资源,并且通过操作这种资源来为它的客户端提供某种服务。—个FTP服务器就管理了一组磁盘文件,它为客户端进行它会为客户端进行存储和检索。相似地一个电子邮件服务器管理了一些文件,它为客户端进行读和更新。

2.客户端-服务器模型中的基本操作是事务

3.事务由四步组成

1)当一个客户端需要服务时,它向服务器发送一个请求,发起一个事务。例如,当Web览器需要一个文件时,它就发送一个请求给Web服务器

2)服务器收到请求后,解释它,并以适当的方式操作它的资源。例如,当Web服务器收到浏览器发出的请求后,它就读一个磁盘文件

3)服务器给客户端发送一响应,并等待下一个请求。例如,Web服务器将文件发送回客户端;

4)客户端收到响应并处理它。例如,当Web浏览器收到来自服务器的一页后,它就在屏幕上显示此页。

网络

客户端和服务器通常运行在不同的话主机上,并且通过计算机网络的硬件和软件资源来通信。

网络的层次系统的最低层时LAN(局域网)

o其技术为以太网

o每个以太网适配器都有一个全球唯一的48未地址。

运行在每台主机和路由器上的协议软件可以解决不兼容的问题。

o两种基本能力:

命名机制

传送机制

主机和路由器如何使用互联网协议在不兼容的局域网间传送数据的示例与步骤。(p617)

因特网域名

1.因特网客户端和服务器互相通信时使用的是IP地址。然而,对于人们而言,大整数是很难记住的,所以因特网也定义了一组更加人性化的域名,以及一种将域名映射到IP地址的机制。域名是一串用句点分隔的单词(字母、数字和破折号)。

2.域名集合形成了一个层次结构,每个域名编码了它在这个层次中的位置。通过一个示例你将很容易理解这点。下展示了域名层次结构的一部分。层次结构可以表示为一棵树。树的节点表示城名,反向到根的路径形成了域名。子树称为子域。层次结构中的第一层是个未命名的根节点。下一层是一组一级域名由非赢利组织(因特网分酒名字数字协会)定义。常见的第一层域名包括com、edu、gov、org、net,这些域名是由ICANN的各个授权代理按照先到先服务的基础分配的的。一旦一个组织得到了一个二级域名,那么它就可以在这个子域中创建任何新的域名了。

因特网连接

一个套接字是连接的一个端点。每个套接字都有相应的套接字地址,是由一个因特网地址和一个16位的整数端口组成的,用“地址:端口”来表示。当客户端发起一个连接请求时,客户端套接字地址中的端口是由内核自动分配的,称为临时端口。然而,服务器套接字地址中的端口通常是某个知名的端口,是和这个服务相对应的。例如,web服务器通常使用端口80,电子邮件服务器使用端口25。

套接字接口

套接字接口是一组用来结合unit I/O函数创建网络应用的函数。

4.1套接字地址结构

从unit内核的角度来看,套接字就是通信的端点;从unix程序的角度来看,套接字就是一个有相应描述
符的打开文件。

4.2 函数

sockte函数
 
创建一个套接字描述符。
connect函数
 
建立和服务器的连接。
open_clientfd函数
 
将socket和connect函数包装而成。客户端可以用它来和服务器建立连接。

bind函数

listen函数

accept函数
 
均被服务器用于和客户端建立连接。

open_listenfd函数
 
socket、bind和listen函数结合。用于服务器创建一个监听描述符。

Web服务器

Web服务器使用HTTP协议和它们的客户端(浏览器等)彼此通信。

浏览器向服务器请求静态或者动态的内容

对静态内容的请求是通过从服务器磁盘取得文件并把它返回给客户端来服务的。

对动态内容的请求时通过在服务器上一个子进程的上下文中运行一个程序并将它的输出返回给客户端来服务的。

CGI标准提供了一组规则,来管理客户端如何将程序参数传递给服务器。服务器如何将这些参数以及其他信息传递给子进程,以及子进程如何将它的输出发送回客户端。

第十二章教材学习内容总结

12.1 基于进程的并发编程

构造并发程序最简单的方法就是用进程。

一个构造并发服务器的自然方法就是,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。

服务器正在监昕一个监听描述符(比如描述符 3)上的连接请求。现在假设服务器接受了客户端 1 的连接请求, 并返回一个已连接描述符(比如描述符4)。

在接受连接请求之后,服务器派生一个子进程,这个子进程获得服务器描述符表的完整拷贝。子进程关闭它的拷贝端的连接请求中的监听描述符 3,而父进程关闭它的己连接描述符 4 的拷贝,因为不再需要这些描述符了。

其中子进程正忙于为客户端提供服务。因为父、子进程中的已连接描述符都指向同一个文件表表项,所以父进程关闭它的已连接描述符的拷贝是至关重要的。否则,将永远不会释放已连接描述符 4 的文件表条目,而且由此 引起的存储器泄漏将最终消耗尽可用的存储器,使系统崩溃。

12.2 基于i/o多路复用的并发编程

1.比如一个服务器,它有两个I/O事件:1)网络客户端发起连接请求,2)用户在键盘上键入命令行。我们先等待那个事件呢?没有那个选择是理想的。如果accept中等待连接,那么无法相应输入命令。如果在read中等待一个输入命令,我们就不能响应任何连接请求(这个前提是一个进程)。

2.针对这种困境的一个解决办法就是I/O多路复用技术。基本思想是:使用select函数,要求内核挂起进程,只有在一个或者多个I/O事件发生后,才将控制返给应用程序。如图所示:横向的方格可以看作是一个n位的描述符向量。现在,我们定义第0位描述是“标准输入”,第3位描述符是“监听描述符”。

基于i/o多路复用的并发事件驱动服务器

I/O多路复用可以用做并发事件驱动程序的基础,在事件驱动程序中,流是因为某种事件而前进的,一般概念是将逻辑流模型化为状态机,不严格地说,一个状态机就是一组状态,输入事件和转移,其中转移就是将状态和输入事件映射到状态,每个转移都将一个(输入状态,输入事件)对映射到一个输出状态,自循环是同一输入和输出状态之间的转移,通常把状态机画成有向图,其中节点表示状态,有向弧表示转移,而弧上的标号表示输人事件,一个状态机从某种初始状态开始执行,每个输入事件都会引发一个从当前状态到下一状态的转移,对于每个新的客户端k,基于I/O多路复用的并发服务器会创建一个新的状态机S,并将它和已连接描述符d联系起来。

i/o多路复用技术的优劣

1.事件驱动设计的一个优点是,它比基于进程的设计给了程序员更多的对程序行为的控制。例如我们可以设想编写一个事件驱动的并发服务器,为某些客户提供他们需要的服务,而这对于新进程的并发服务器来说,是很困难的

2.另一个优点是,一个基于I/O多路复用的事件驱动器是运行在单一进程上下文中的,因此每个逻辑流都能访问该进程的全部地址空间。这使得在流之间共享数据变得很容易,一个与作为单个进程运行相关的优点是,你可以利用熟悉的调试工具,例如GDB,来调试你的并发服务器,就像对顺序程序那样。最后,事件驱动设计常常比基于进利的设计要高效得多,因为它们不需要进程上下文切换来调度新的流。

3.事件驱动设计的一个明显的缺点就是编码复杂,我们的事件驱动的并发服务器需要的代度是指每个逻辑流每个时间片执行的指令数量。基于事件的设计的另一个重大缺点是它们不能充分利利用多核处理器。

12.3基于线程的并发编程

每个线程都有自己的线程上下文,包括一个线程ID、栈、栈指针、程序计数器、通用目的寄存器和条件码。所有的运行在一个进程里的线程共享该进程的整个虚拟地址空间。由于线程运行在单一进程中,因此共享这个进程虚拟地址空间的整个内容,包括它的代码、数据、堆、共享库和打开的文件。

12.4多线程程序中的共享变量

全局变量和static变量是存储在数据段,所以多线程共享之!由于线程的栈是独立的,所有线程中的自动变量是独立的。即使多个线程运行同一段代码总的自动变量,那么他们的值也是根据线程的不同而不同。

12.5 用信号量同步线程

同步错误。

将线程 i 的循环代码分解成五个部分:

Hi:在循环头部的指令块

Li:加载共享变量 cnt 到寄存器%eaxi 的指令,这里%eaxi 表示线程i 中的寄存器%eax的值。

Ui:更新(增加) %eaxi 的指令。

Si:将%eaxi 的更新值存回到共享变量 cnt 的指令。

Ti:循环尾部的指令块。

注意头和尾只操作本地栈变量,而 Li、 Ui 和 Si操作共享计数器变量的内容。
 
一般而言, 你没有办法预测操作系统是否将为你的线程选择一个正确的顺 序。
 
进度图 (progress graph) 的方法来阐明这些正确 的和不正确的指令顺序的概念。

12.6 使用线程提高并行性

到目前为止,在对并发的研究中,我们都假设并发线程是在单处许多现代机器具有多核处理器。并发程序通常在这样的机器上运理器系统上执行的。然而,在多个核上并行地调度这些并发线程,而不是在单个核顺序地调度,在像繁忙的Web服务器、数据库服务器和大型科学计算代码这样的应用中利用这种并行性是至关重要的。

教材学习中的问题和解决过程

Q:多线程编程的好处是什么?

A:在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态。多个线程共享堆内存(heap memory),因此创建多个线程去执行一些任务会比创建多个进程更好。举个例子,Servlets比CGI更好,是因为Servlets支持多线程而CGI不支持。

代码托管

代码学习中的问题和解决过程

在socket代码运行过程中,编译之时出现这种错误提示:WSAEINVAL (10022)
错误原因:翻译 : 无效参数。

说明 : 对 setsockopt (Wsapiref_94aa.asp) 函数提供一个无效参数指定了无效层 (例如, 一个参数)。 有时, 它也指向当前状态的套接字, 例如, 调用接受 (Wsapiref_13aq.asp) 套接字,没有侦听上。

https://gitee.com/bestiisjava2017/yxc20155302/tree/master/src/信息安全系统设计基础20155302

其他(感悟、思考等,可选)

无论哪种并发机制,同步对共享数据的并发访问都是一个困难的问题。提出对信号量的 P 和 V操作就是为了帮助解决这个问题。信号量操作可以用来提供对共享数据的互斥访问,也对诸如生产者一消费者程序中有限缓冲区和读者一写者系统中的共享对象这样的资源访问进行调度。 
并发也引人了其他一些困难的问题。被线程调用的函数必须具有一种称为线程安全的属性。 
可重入函数是线程安全函数的一个真子集,它不访问任何共享数据。可重入函数通常比不可重人函数更为有效,因为它们不需要任何同步原语。竞争和死锁是并发程序中出现的另一些困难的问题。当程序员错误地假设逻辑流该如何调度时,就会发生竞争。当一个流等待一个永远不会发生的事件时,就会产生死锁。

原文地址:https://www.cnblogs.com/STILLlover521/p/7823117.html