zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155320 《信息安全系统设计基础》第八周学习总结

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

    教材学习内容总结

    第十一章 网络编程

    • 每个网络应用都是基于客户端一服务器模型的。一个应用是由一个服务器进程和一个或者多个客户端进程组成。服务器管理某种资源,并且通过操作这种资源来为它的客户端提供某种服务。

    客户端一服务器模型中的基本操作是事务,一个客户端-服务器由四步组成:

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

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

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

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

    • 客户端和服务器是进程而不是主机。
    • 客户端和服务器通常运行在不同的主机上,并且通过计算机网络的硬件和软件资源来通信。
    • 每个以太网适配器都有全球唯一的48位地址。
    • 使用一些电缆和叫做网桥 (bridge) 的小盒子,多个以太网段可以连接成较大的局域网,称为桥接以太网 (bridged Ethernet)桥接以太网

    -网桥比集线器更充分地利用了电缆带宽。

    • 在层次的更高级别中,多个不兼容的局域网可以通过叫做路由器 (router)的特殊计算机连接起来,组成一个internet(互联网络)。

    Internet 和 internet 我们总是用小写字母的 internet 描述一般概念, 而用大写字母的Internet 来描述一种具体的实现,也就是所谓的全球 IP 因特网。

    • 互联网至关重要的特性是,它能由采用完全不同和不兼容技术的各种局域网和广域网组成。
    • 全球IP因特网是最著名和最成功的互联网络实现。
    • 展示一个因特网客户端-服务器应用程序的基本硬件和软件组织。

    • 每台因特网主机都运行实现 TCP/IP 协议 (Transmission Control Protocol/Internet Protocol,传输控制协议/互联网络协议)的软件,几乎每个现代计算机系统都支持这个协议。

    • 每台因特网主机都运行实现TCP/IP协议。因特网的客户端和服务器混合使用套接字接口函数和 Unix I/O 函数来进行通信。套接字函数典型地是作为会陷入内核的系统调用来实现 的,并调用各种内核模式的 TCP/IP 函数。

    • TCP/IP实际是一个协议族。

    • 一个 IP 地址就是一个 32 位无符号整数。

    • htonl 函数将32 位整数由主机字节顺序转换为网络字节顺序。

    • ntohl 函数将 32 位整数从网络宇节顺序转换为主机字节。

    • htons和 ntohs 函数为 16 位的无符号整数执行相应的转换。

    • IP 地址通常是以一种称为点分十进制表示法来表示的。

    • 在linux系统上,你能够使用HOSTNAME来确定自己的点分十进制地址。

    • 应用程序使用inet_pton和inet_ntop函数来实现IP地址和点分十进制串之间的转换。

    • "n" 表示的是网络(network)。"a" 表示应用(application)。而 "to" 表示转换。

    • 因特网客户端和服务器互相通信时使用的是 IP 地址。

    • 常见的第一层域名包括 com、 edu、 gov、org 和 net。

    • 下一层是二级 (second-level) 域名,例如 cmu. edu

    • 一旦一个组织得到了一个二级域名,那么它就可以在这个子域中创建任何新的域名了。

    • 因特网定义了域名集合和 IP 地址集合之间的映射。

    • 因特网应用程序通过调用 gethostbyname 和 gethostbyaddr 函数,从 DNS 数据库中检索任意的主机条目。

    • Web 服务器通常使用端口 80,而电子邮件服务器使用端口 25。

    套接字接口 (socket interface) 是一组函数,它们和 Unix I/O 函数结合起来,用以创建网络应用。

    套接字接口描述:

    socket 函数

    客户端和服务器使用 socket 函数来创建一个套接字描述符

    connect 函数

    客户端通过调用 connect 函数来建立和服务器的连接。

    open_clientfd 函数

    open_clientfd 函数和运行在主机 hostname 上的服务器建立一个连接,并在知名端口 port 上监听连接请求。它返回一个打开的套接宇描述符,该描述符准备好了,可以用 Unix I/O 函数做输入和输出。

    ** bind 函数**

    bind、 listen 和 accept 被服务器用来和客户端建立连接。

    bind 函数告诉内核将 my_addr中的服务器套接字地址和套接字描述符 sockfd 联系起来。参数 addrlen 就是 sizeof(sockaddr_in) 。

    ** listen 函数**

    listen 函数将 sockfd 从一个主动套接字转化为一个监听套接字 (listening socket),该套接字可以接受来自客户端的连接请求。

    open_listenfd 函数

    socket、 bind 和 listen 函数结合成一个叫做。open_listenfd 的辅助函数

    ** accept 函数**

    accept 函数来等待来自客户端的连接请求

    accept 函数等待来自客户端的连接请求到达侦听描述符 listenfd,然后在 addr 中填写客户端的套接字地址,并返回一个巳连接描述符 (connected descriptor),这个描述符可被用来利用 Unix I/O 函数与客户端通信。

    • Web 客户端和服务器之间的交互用的是一个基于文本的应用级协议,叫做 HTTP (Hypertext Transfer Protocol,超文本传输协议). HTTP 是一个简单的协议。

    • 一个 Web 客户端(即浏览器) 打开一个到服务器的因特网连接,并且请求某些内容。服务器响应所请求的内容,然后关闭连接。浏览器读取这些内容,并把它显示在屏幕上。

    • 每条由 Web 服务器返回的内容都是和它管理的某个文件相关联的。这些文件中的每一个都有一个唯一的名字,叫做 URL (Universal Resource Locator,通用资源定位符)。

    • 因为 HTTP 是基于在因特网连接上传送的文本行的,我们可以使用 Unix 的TELNET程序来和因特网上的任何 Web 服务器执行事务。

    • 一个 HTTP 请求的组成是这样的:一个请求行 (request line) (第 5 行),后面跟随零个或更多个请求报头 (request header) (第 6 行),再跟随一个空的文本行来终止报头列表

    HTTP 支持许多不同的方法,包括 GET、 POST、 OPTIONS、 HEAD、 PUT、 DELETE 和 TRACE。

    第十二章 并发编程

    • 三种基本的构造并发程序的方法:
      进程

    每个逻辑控制流是一个进程,由内核进行调度,进程有独立的虚拟地址空间

    I/O多路复用

    逻辑流被模型化为状态机,所有流共享同一个地址空间

    线程

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

    • 基于进程的并发服务器

    1.使用SIGCHLD处理程序来回收僵死子进程的资源。

    2.父进程必须关闭他们各自的connfd拷贝(已连接的描述符),避免存储器泄露。

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

    **关于独立地址空间

    优点:防止虚拟存储器被错误覆盖

    缺点:开销高,共享状态信息才需要IPC机制**

    • 使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序。

    • 对描述符集合的处理方法:

    1.分配他们

    2.将一个此种类型的变量赋值给另一个变量

    3.用FD_ZERO,FD_SET,FD_CLR和FD_ISSET宏指令来修改和检查他们。

    • 基于I/O多路复用的并发事件驱动服务器

    1.I/O多路复用可以用作事件并发驱动程序的基础。

    2.状态机:一组状态、输入事件、输出事件和转移。

    3.自循环:同一输入和输出状态之间的转移。

    • I/O多路复用技术的优劣

    优点:相比基于进程的设计给了程序员更多的对进程行为的控制,运行在单一进程上下文中,每个逻辑流都能访问全部的地址空间,在流之间共享数据很容易。

    缺点:编码复杂,随着并发粒度的减小,复杂性还会上升。粒度:每个逻辑流每个时间片执行的指令数量。

    • 每个进程开始生命周期时都是单一线程(主线程),在某一时刻创建一个对等线程,从此开始并发地运行,最后,因为主线程执行一个慢速系统调用,或者被中断,控制就会通过上下文切换传递到对等线程。
      Posix线程

    • Posix线程是C语言中处理线程的一个标准接口,允许程序创建、杀死和回收线程,与对等线程安全的共享数据。

    • 创建线程

    线程通过调用pthread_create来创建其他线程。

    int pthread_create(pthread_t *tid,pthread_attr_t *attr,func *f,void *arg);
    成功则返回0,出错则为非零
    
    • 当函数返回时,参数tid包含新创建的线程的ID,新线程可以通过调用pthread_self函数来获得自己的线程ID。
    pthread_t pthread_self(void);
    返回调用者的线程ID。
    
    • 终止线程
      一个线程是通过以下方式之一来终止的。

    当顶层的线程例程返回时,线程会隐式地终止。
    通过调用pthread_exit函数,线程会显式地终止

    void pthread_exit(void *thread_return);
    
    
    • 回收已终止的线程资源
      线程通过调用pthread_join函数等待其他线程终止。
    int pthread_join(pthread_t tid,void **thread_return);
    成功则返回0,出错则为非零
    
    
    • 分离线程
      在任何一个时间点上,线程是可结合或可分离的。一个可结合的线程能够被其他线程收回其资源和杀死,在被回收之前,它的存储器资源是没有被释放的。分离的线程则相反,资源在其终止时自动释放。

    int pthread_deacth(pthread_t tid);
    成功则返回0,出错则为非零

    初始化线程
    pthread_once允许初始化与线程例程相关的状态。

    pthread_once_t once_control=PTHREAD_ONCE_INIT;
    int pthread_once(pthread_once_t once_contro,
    void (
    init_routine)(void));
    总是返回0

    • 线程存储器模型

    1.每个线程都有自己独立的线程上下文,包括一个唯一的整数线程ID,栈、栈指针、程序计数器、通用目的寄存器和条件码。

    2.寄存器是从不共享的,而虚拟存储器总是共享的。

    3.各自独立的线程栈被保存在虚拟地址空间的栈区域中,并且通常是被相应的线程独立地访问的。

    • 将变量映射到存储器

    1.全局变量:定义在函数之外的变量

    2.本地自动变量:定义在函数内部但是没有static属性的变量。

    本地静态变量:定义在函数内部并有static属性的变量。

    • 共享变量

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

    • 信号量

    1.P(s):如果s是非零的,那么P将s减一,并且立即返回。如果s为零,那么就挂起这个线程,直到s变为非零。

    2.V(s):将s加一,如果有任何线程阻塞在P操作等待s变为非零,那么V操作会重启线程中的一个,然后该线程将s减一,完成他的P操作。
    信号量不变性:一个正确初始化了的信号量有一个负值。

    • 二元信号量(互斥锁):将每个共享变量与一个信号量s联系起来,然后用P(s)(加锁)和V(s)(解锁)操作将相应的临界区包围起来。

    • 禁止区:s<0,因为信号量的不变性,没有实际可行的轨迹线能够直接接触不安全区的部分

    • 并行程序的加速比通常定义为:
      Sp=T1/Tp

    其中,p为处理器核的数量,T为在p个核上的运行时间

    • 一个线程是安全的,当且仅当被多个并发线程反复的调用时,它会一直产生正确的结果。

    • 可重入性
      当它们被多个线程调用时,不会引用任何共享数据。

    显式可重入的:
    所有函数参数都是传值传递,没有指针,并且所有的数据引用都是本地的自动栈变量,没有引用静态或全剧变量。

    隐式可重入的:
    调用线程小心的传递指向非共享数据的指针。

    竞争

    • 产生竞争的原因:
      一个程序的正确性依赖于一个线程要在另一个线程到达y点之前到达它的控制流中的x点。也就是说,程序员假定线程会按照某种特殊的轨迹穿过执行状态空间,忘了一条准则规定:线程化的程序必须对任何可行的轨迹线都正确工作。

    • 消除竞争方法:
      动态的为每个整数ID分配一个独立的块,并且传递给线程例程一个指向这个块的指针

    死锁

    一组线程被阻塞了,等待一个永远也不会为真的条件。

    • 解决死锁的方法

    1.不让死锁发生:

    • 静态策略:设计合适的资源分配算法,不让死锁发生---死锁预防;
    • 动态策略:进程在申请资源时,系统审查是否会产生死锁,若会产生死锁则不分配---死锁避免。

    2.让死锁发生:

    进程申请资源时不进行限制,系统定期或者不定期检测是否有死锁发生,当检测到时解决死锁----死锁检测与解除。

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

    • 问题1:
      线程与进程的区别

    • 问题1解决方案:

    一个程序至少有一个进程,一个进程至少有一个线程.
    线程的划分尺度小于进程,使得多线程程序的并发性高。

    线程是指进程内的一个执行单元,也是进程内的可调度实体.
    与进程的区别:

    (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;

    (2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源

    (3)线程是处理器调度的基本单位,但进程不是.

    (4)二者均可并发执行.
    进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于:

    代码调试中的问题和解决过程

    • 问题1:在做客户端与服务器的实践,运行时总会出现权限不够的提示:

    • 问题1解决方案:后来发现在命令前加上sudo,给予root权限就可以了

    • 问题2:其他问题在上一篇博客里

    代码托管

    结对及互评

    本周结对学习情况

    • 结对学习内容

      • 第十一章、第十二章内容

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

    本周学习的内容刘念老师的课程关联性很强,但是在实践中仍然需要自己解决许多问题,

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 200小时
    第一周 5/5 1/1 15/15
    第二周 1/2 23/38
    第三周 206/327 1/3 28/66
    第四周 206/327 1/4 10/77
    第五周 285/568 1/5 20/97 主要学习了汇编及反汇编的相关知识
    第六周 160/683 3/8 20/107
    第七周 / 2/10 20/127 第四章学习内容和第二次实验
    第八周 /2304 2/12 22/149 第十一章、第十二章

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    参考资料

  • 相关阅读:
    JS,JQ及时监听input值的变化,MUI的input搜索框里的清除按钮的点击监听事件
    MUI 底部弹出的选择框
    MUI 拍照或选取照片上传作为头像
    多行文本文本输入框 textarea 可点击任意地方编辑的问题
    mui dtpicker 时间的设置 以及MUI的弹窗
    MUI 样式按钮的禁用
    利用渐变实现书本的效果
    调用sqlserver中的存储过程
    XmlHelper
    面试题 数据库sql
  • 原文地址:https://www.cnblogs.com/ljq1997/p/7822214.html
Copyright © 2011-2022 走看看