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

Posted maxeysblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-2019-1 20165325 《信息安全系统设计基础》第八周学习总结相关的知识,希望对你有一定的参考价值。

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

一、学习笔记——网络编程

1、三种并发方式

构造并发程序的方法有三种:

  • 进程
  • 线程
  • I/O多路复用

进程:用内核来调用和维护,有独立的虚拟地址空间,显式的进程间通信机制。

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

I/O多路复用:应用程序在一个进程的上下文中显式地调度控制流。逻辑流被模型化为状态机。

2、C/S编程模型

客户端和服务器都是进程,C/S编程模型由一个服务器进程和一个或多个客户端进程组成

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

  • 客户端向服务器发送请求,发起一个事务;

  • 服务器收到请求,操作资源;

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

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

3、线程控制及相关系统调用

在上一次的socket编程中,服务器持续listen,如果有客户端进程请求,服务器父进程就会派生一个子进程来处理新的连接请求。这便存在基于进程的并发编程。

socket编程

线程:运行子进程上下文中的逻辑流

线程与进程的不同:

  • 线程的上下文切换要比进程的上下文切换快得多;

  • 和一个进程相关的线程组成对等,独立于其他线程创建的线程。

  • 主线程和其他线程的区别仅在于它总是进程中第一个运行的线程。

创建线程

pthread create:创建一个新的线程,在新线程的上下文中运行线程例程f。

新线程可以通过pthread _self获得自己的线程ID。

终止线程

一个线程的终止方式:

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

  • pthread_exit:线程显式地终止。

注:如果主线程调用pthread _exit,它会等待所有其他对等线程终止,然后再终止主线程和整个进程。

回收已终止线程的资源

pthread _join:阻塞,直到线程tid终止,回收已终止线程占用的所有存储器资源。

注:pthread _join只能等待一个指定的线程终止。

分离线程
  • 在任何一个时间点上,线程是可结合的或者是分离的。一个可结合的线程能够被其他线程收回其资源和杀死;一个可分离的线程是不能被其他线程回收或杀死的。它的存储器资源在它终止时有系统自动释放。

  • 默认情况下,线程被创建成可结合的,为了避免存储器漏洞,每个可集合的线程都应该要么被其他进程显式的回收,要么通过调用pthread _detach被分离。

初始化线程

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

二、Linux实现命令——mypwd

1、pwd命令学习

在Linux中使用man命令查看pwd:

技术分享图片

实际操作使用pwd命令:

技术分享图片

pwd命令的作用是查看当前所在的工作路径。

2、思路

基本原理:

每个目录下都至少有两个内容‘.’和’..’,其中‘.’代表当前目录,’..’代表父目录。每个目录或文件都有对应的i-节点号。

$ ls -1ia(数字1,不是字母l):查看当前目录下的文件名和对应的i-节点号。

伪代码不会写(写出来不规范,可能只有自己看得懂),思路大概是:

  • 查看本目录的i-节点,找到父目录;

  • 进入父目录,输出其i-节点对应的文件夹名;

  • 循环以上过程直到到达根目录;

注:首先找到的目录是较小的子目录,最后才读取到根目录。但是输出是从根目录开始的。

典型的输入输出逆序问题,一般两种解决方案:一是用栈,二是用递归。

这里我使用递归实现。

判断是否抵达根目录

根目录的‘.’和’..’相同,i-节点号相同。

用到的核心函数
  • stat(char* fname, struct stat* bufp);把文件fname的信息复制到bufp所指结构体里(stat结构体包含了文件的信息,在/user/include/sys/stat.h中可以看到struct stat的成员变量。);

  • readdir(DIR* dir_ptr)读取dir_ptr目录的所有文件和目录,返回值是struct dirent结构体;每次调用都会指向下一个文件,遍历完后返回值为NULL;

  • chdir

3、实现mypwd

代码:

///////////////////////////////////////////
//mypwd.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
void mypwd(ino_t this_inode);
void inum_to_name(ino_t inode_to_find,char* namebuf,int buflen);
ino_t get_inode(char* fname);
//返回文件的i节点
ino_t get_inode(char* fname)            
{
    struct stat info;
    if (stat(fname, &info) == -1){
    fprintf( stderr , "Cannot stat ");
    perror(fname);
    exit (1);
    }
    return info.st_ino;
}
void mypwd(ino_t this_inode)
{
    ino_t my_inode;
    char its_name[BUFSIZ];
    //检查本目录是不是根目录
    if (get_inode("..")!=this_inode)                                 
    {
        //进入上级目录
        chdir("..");         
        inum_to_name(this_inode,its_name,BUFSIZ);
        my_inode = get_inode(".");
        mypwd(my_inode);
        printf("/%s",its_name);
    }
}
//找到i节点对应的文件名,并放在字符数组里
void inum_to_name(ino_t inode_to_find,char* namebuf,int buflen)   
{
    DIR* dir_ptr;
    struct dirent* direntp;
    dir_ptr = opendir(".");
    if (dir_ptr == NULL)
    {
        perror(".");
        exit(1);
    }
    //寻找指定i节点的目录,将目录名复制到namebuf中。
    while((direntp = readdir(dir_ptr)) != NULL)
    {
        if(direntp->d_ino == inode_to_find)
        {
        strncpy(namebuf,direntp->d_name,buflen);
        namebuf[buflen-1] = '';
        closedir(dir_ptr);
        return;
        }
    }
    fprintf( stderr , "ERROR while looking for inum %d : NOT FOUND!
",(int)inode_to_find);
    exit (1);
}
int main()
{
    //显示路径
    mypwd(get_inode("."));  
    putchar('
');
    return 0;
}

4、测试mypwd

技术分享图片

以上是关于2018-2019-1 20165325 《信息安全系统设计基础》第八周学习总结的主要内容,如果未能解决你的问题,请参考以下文章

20165325《Java程序设计》第九周学习总结

20165325 预备作业3 Linux安装及学习

20165301陈潭飞2017-2018-2 20165325 实验三《Java面向对象程序设计》实验报告

2018-2019-1 《信息安全系统设计基础》 20165235 实验五 通信协议设计

2018-2019-1 20165236 《信息安全系统设计基础》第4周学习总结

2018-2019-1 20175234 《信息安全系统设计基础》有关系统调用的部分学习