20155212 2017-2018-1 《信息安全系统设计》第10周学习总结

20155212 2017-2018-1 《信息安全系统设计》第10周学习总结

stat命令的实现-mysate

  • 要求:学习使用stat(1),并用C语言实现
  • 学习stat(1)
    • 功能:显示文件或者文件系统信息
    • 语法stat [选项] 文件
    • 选项参数
      • null:显示详细信息
      • -l:链接
      • -f:不显示文件的信息,而显示其所在文件系统的信息
      • -t:显示简洁的信息
      • -c:以指定格式输出
    • man 1 stat查看stat命令
    • 使用stat命令
  • 使用man -k stat | grep 2函数找到如下
  • 使用man 2 stat查看
  • 使用stat()函数会获得stat结构体
    struct stat
    {
        dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/
        ino_t       st_ino;     /* inode number -inode节点号*/
        mode_t      st_mode;    /* 文件的类型和存取的权限*/
        nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/
        uid_t       st_uid;     /* user ID of owner -user id*/
        gid_t       st_gid;     /* group ID of owner - group id*/
        dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/
        off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/
        blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/
        blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/
        time_t      st_atime;   /* time of last access -最近存取时间*/
        time_t      st_mtime;   /* time of last modification -最近修改时间*/
        time_t      st_ctime;   /* time of last status change - */
    };    

    其中,比较特殊的是st_mode,st_mode是用特征位来表示文件类型的,特征位的定义如下:

    S_IFMT      0170000     文件类型的位遮罩
    S_IFSOCK    0140000     socket
    S_IFLNK     0120000     符号链接(symbolic link)
    S_IFREG     0100000     一般文件
    S_IFBLK     0060000     区块装置(block device)
    S_IFDIR     0040000     目录
    S_IFCHR     0020000     字符装置(character device)
    S_IFIFO     0010000     先进先出(fifo)
    S_ISUID     0004000     文件的(set user-id on execution)位
    S_ISGID     0002000     文件的(set group-id on execution)位
    S_ISVTX     0001000     文件的sticky位
    S_IRWXU     00700       文件所有者的遮罩值(即所有权限值)
    S_IRUSR     00400       文件所有者具可读取权限
    S_IWUSR     00200       文件所有者具可写入权限
    S_IXUSR     00100       文件所有者具可执行权限
    S_IRWXG     00070       用户组的遮罩值(即所有权限值)
    S_IRGRP     00040       用户组具可读取权限
    S_IWGRP     00020       用户组具可写入权限
    S_IXGRP     00010       用户组具可执行权限
    S_IRWXO     00007       其他用户的遮罩值(即所有权限值)
    S_IROTH     00004       其他用户具可读取权限
    S_IWOTH     00002       其他用户具可写入权限
    S_IXOTH     00001       其他用户具可执行权限  

    判断文件类型时,用对文件的st_mode的值与文件类型的位遮罩相与,再比较。

  • stat结构体中很多变量的类型都是不常用的,不能直接输出该类型,所以使用grep -r *查找同名变量的类型。以存储大小的变量st_size为例,发现很多使用的long long类型
  • 伪代码
input path;
struct state;
stat(path,state);
print(state);
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

void main(int argc, char *argv[])
{
    struct stat state;

    stat(argv[1], &state);

    printf("  文件:‘%s‘\n", argv[1]);
    printf("  大小:%lld\t", (long long)state.st_size);
    printf("块:%lld\t", (long long)state.st_blocks);
    printf("IO块:%ld\t", (long)state.st_blksize);
    switch(state.st_mode & S_IFMT)
    {
    case S_IFBLK:
        printf("块设备文件");
        break;
    case S_IFCHR:
        printf("字符设备文件");
        break;
    case S_IFDIR:
        printf("目录");
        break;
    case S_IFIFO:
        printf("管道文件");
        break;
    case S_IFLNK:
        printf("符号链接文件");
        break;
    case S_IFREG:
        printf("普通文件");
        break;
    case S_IFSOCK:
        printf("套接字文件");
        break;
    default:
        break;
    }
    printf("\n");

    printf("设备:%xh/%ldd\t", (long)state.st_dev, (long)state.st_dev);
    printf("Inode:%ld\t", (long)state.st_ino);
    printf("硬链接:%ld\n", (long)state.st_nlink);
    printf("权限:(%o)\t", (unsigned int)(state.st_mode & ~S_IFMT));
    printf("Uid:(%ld)\t", (long)state.st_uid);
    printf("Gid:(%ld)\n", (long)state.st_gid);
    printf("最近访问:%s", ctime(&state.st_atim));
    printf("最近更改:%s", ctime(&state.st_ctim));
    printf("最近改动:%s", ctime(&state.st_mtim));
    printf("创建时间:-");
    printf("\n");
}
  • 测试代码,mystat 与stat(1)对比,提交截图

Linux下IPC机制

进程间通信(IPC,Inter-Process Communication)指至少两个进程或线程间传送数据或信号的一些技术或方法。

共享内存

共享内存允许两个或多个进程共享一定的存储区,因为不需要拷贝数据,所以这是最快的一种IPC。

  • 原理:

    共享内存是在多个进程之间共享内存区域的一种进程间的通信方式,由IPC为进程创建的一个特殊地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到自己的地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是malloc分配的一样。如果一个进程向共享内存中写入了数据,所做的改动将立刻被其他进程看到。

    • 内存头文件

      #include <sys/types.h>
      #include <sys/stat.h>
      #include <sys/shm.h>  
    • 结构shmid_ds结构体(类似msgid_ds结构体)
    strcut shmid_ds{
        struct ipc_perm    shm_perm;
        size_t    shm_segsz;
        time_t    shm_atime;
        time_t    shm_dtime;
        ......
    }  
    • 共享内存函数定义
    int shmget(key_t key,size_t size,int shmflg);  //shmget函数用来创建一个新的共享内存段, 或者访问一个现有的共享内存段(不同进程只要key值相同即可访问同一共享内存段)。第一个参数key是ftok生成的键值,第二个参数size为共享内存的大小,第三个参数sem_flags是打开共享内存的方式
    eg.int shmid = shmget(key, 1024, IPC_CREATE | IPC_EXCL | 0666);//第三个参数参考消息队列int msgget(key_t key,int msgflag);
    void *shmat(int shm_id,const void *shm_addr,int shmflg); //shmat函数通过shm_id将共享内存连接到进程的地址空间中。第二个参数可以由用户指定共享内存映射到进程空间的地址,shm_addr如果为0,则由内核试着查找一个未映射的区域。返回值为共享内存映射的地址
    eg.char *shms = (char *)shmat(shmid, 0, 0);//shmid由shmget获得
    int shmdt(const void *shm_addr) //shmdt函数将共享内存从当前进程中分离。 参数为共享内存映射的地址。
    eg.shmdt(shms)
    int shmctl(int shm_id,int cmd,struct shmid_ds *buf);//shmctl函数是控制函数,使用方法和消息队列msgctl()函数调用完全类似。参数一shm_id是共享内存的句柄,cmd是向共享内存发送的命令,最后一个参数buf是向共享内存发送命令的参数。 
  • 特点
    • 共享内存允许两个或多个进程共享一定的存储区,因为不需要拷贝数据,所以这是最快的一种IPC
    • 共享内存本身并没有同步机制,需要程序员使用诸如信号量等手段进行同步控制,增加了其复杂性
  • 示例
    • 写进程

      • 代码

        ```

        include

        include

        include <sys/shm.h>

        include

        include

        include <sys/types.h>

        include <sys/ipc.h>

        include

      define BUF_SIZE 4096

      int main()

      {

      void *shm_addr = NULL;

      char buffer[BUF_SIZE];

      int shmid;
      // 使用约定的键值创建共享内存
      shmid = shmget((key_t) 1234,  BUF_SIZE, 0666 | IPC_CREAT);
      printf("shmid : %u\n", shmid);
      if (shmid < 0)
      {
          perror("shmget error!");
          exit(1);
      }
      
      // 将共享内存附加到本进程
      shm_addr = shmat(shmid, NULL, 0);
      if (shm_addr == (void *) -1)
      {
          perror("shmat error!");
          exit(1);
      }
      
      // 写入数据
      bzero(buffer, BUF_SIZE);
      sprintf(buffer, "Hello, My PID is %u\n", (unsigned int) getpid());
      printf("send data: %s\n", buffer);
      
      memcpy(shm_addr, buffer, strlen(buffer));
      
      sleep(5);
      
      // 分离
      if (shmdt(shm_addr) == -1)
      {
          printf("shmdt error!\n");
          exit(1);
      }

      }

      ``- 运行结果![](https://images2018.cnblogs.com/blog/1043723/201711/1043723-20171126165304640-412383960.png) -ipcs -m`命令查看系统中的确存在标识符为15466507的共享内存区域。写进程已经跟共享内存分离,所以状态连接数为0

    • 读进程
      • 代码
      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/shm.h>
      #include <sys/ipc.h>
      #include <sys/types.h>
      #include <unistd.h>
      #include <string.h>
      #include <errno.h>
      
      #define BUF_SIZE 4096
      
      int main()
      {
          void *shm_addr = NULL;
      
          int shmid;
          // 使用约定的键值打开共享内存
          shmid = shmget((key_t) 1234, BUF_SIZE, IPC_CREAT);
          printf("shmid : %u\n", shmid);
          if (shmid == -1)
          {
              perror("shmget error!");
              exit(1);
          }
      
          // 将共享内存附加到本进程
          shm_addr = shmat(shmid, NULL, 0);
          if (shm_addr == (void *) -1)
          {
              perror("shmat error!");
              exit(1);
          }
      
          // 读取数据
          char tmp[BUF_SIZE];
          bzero(tmp, BUF_SIZE);
          memcpy(tmp, shm_addr, BUF_SIZE);
          printf("read from shared memory: %s\n", tmp);
      
          sleep(5);
      
          // 分离
          if (shmdt(shm_addr) == -1)
          {
              printf("shmdt error!\n");
              exit(1);
          }
      
          // 删除共享内存
          if (shmctl(shmid, IPC_RMID, 0) == -1)
          {
              printf("shmctl error!\n");
              exit(1);
          }
      }
      • 运行结果
      • ipcs -m查看,没有15466507的进程,因为读进程执行完毕后删除了共享内存区域

管道

在Linux系统中,我们经常通过符号“|”来使用管道,用以连接两个或多个命令。实际上,管道是进程与进程间的数据流通道,它使得数据可以以一种“流”的形式在进程间流动。管道也是Unix/Linux系统中一种最常见的进程间通信方式,它在两个通信进程之间实现一个数据流的通道从而进行信息传递。

  • 原理

    • 在两个程序之间传递数据的最简单的方法是使用popen()和pclose()函数

      #include <stdio.h>
      FILE *popen(const char *command, const char *open_mode);
      int pclose(FILE *stream);

      popen()函数首先调用一个shell,然后把command作为参数传递给shell。这样每次调用popen()函数都需要启动两个进程;但是由于在Linux中,所(parameter expansion)都是由shell执行的,这样command中包含的所有参数扩展都可以在command程序启动之前完成。

    • pipe()函数

      #include <sys/types.h>
      #include <sys/stat.h>
      int mkfifo(const char *fifo_name, mode_t mode);

      popen()函数只能返回一个管道描述符,并且返回的是文件流(file stream),可以使用函数fread()和fwrite()来访问。pipe()函数可以返回两个管道描述符:pipefd[0]和pipefd[1],任何写入pipefd[1]的数据都可pipefd[0]读回;pipe()函数返回的是文件描述符(file descriptor),因此只能使用底层的read()和write()系统调用来访问。pipe()函数通常用来实现父子进程之间的通信。

  • 特点
    • 只支持单向数据流
    • 只能用于具有亲缘关系的进程之间;
    • 没有名字
    • 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小)
    • 管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等
  • 示例: 构造父子进程间任意方向的的数据通道
    • 代码
    • 运行结果

FIFO

  • 原理
  • 特点
  • 示例

信号

  • 原理
  • 特点
  • 示例

消息队列

  • 原理
  • 特点
  • 示例

参考

时间: 2024-12-09 16:11:30

20155212 2017-2018-1 《信息安全系统设计》第10周学习总结的相关文章

20155204 信息安全系统设计 第十周 课上测试补交

20155204 信息安全系统设计 第十周 课上测试补交 我的答案:D 我的答案:ACD 我的答案:ACD 我的答案:ABC 我的答案:ABCD 我的答案:A 我的答案:C 我的答案:C 我的答案:C 我的答案:ABD 我的答案:ABCD 我的答案:B 我的答案:A 我的答案:ABC 我的答案:C 我的答案:ACD 我的答案:BDE 我的答案:CE 我的答案:C 我的答案:ADEG 我的答案:BCD 总分:16

信息安全设计基础第十周学习总结

信息安全设计基础第十周学习总结 [学习时间:8小时]  [学习内容:教材第十章 之 I/O总结:实验楼私有课程<深入理解计算机系统> 之 系统级I/O] 一.教材内容 1.I/O重定向 [重定向其实是unix系统优越性的一种体现(与管道相似):将一种操作的结果重定向到另外一种操作上,这样的思想保证了“专务专用”,将单个操作做到极致,又为用户自己提供了完善功能的平台(比如重定向,比如管道).] - unix外壳提供了I/O重定向操作符,允许用户将磁盘文件和标准输入输出连接起来.例如: ls &g

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

2017-2018-1 20155212 <信息安全系统设计基础>第14周学习总结 教材学习内容总结 客户端-服务器模型 客户端-服务器模型中的基本操作是事物 客户端发送请求 服务器解释请求,并以适当的方式操作资源 服务器发送响应*,并等待下一个请求 客户端收到响应并处理 客户端和服务器是进程而不是主机 网络 对主机而言,网络只是一种I/O设备,是数据源和数据接收方 协议:消除了不同网络之间的差异 命名机制:定义一种一致的主机地址 传送机制:定义一种把数据位捆扎 数据传送过程 TCP/IP与O

20175312 2018-2019-2 《Java程序设计》第10周学习总结

20175312 2018-2019-2 <Java程序设计>第10周学习总结 教材学习内容总结 已依照蓝墨云班课的要求完成了第十二章的学习,主要的学习渠道是PPT,和书的课后习题. 总结如下: 1.第十二章的主要内容: Java中的线程 Thread类与线程的创建 线程的常用方法 线程同步 协调同步的线程 线程联合 GUI线程 计时器线程 2.除了课本内容,还学习了有关--数据库MySQL(课下作业,必做)的内容 3.课本代码已经上传至码云,链接如下: https://gitee.com/d

20145331 《Java程序设计》第10周学习总结

20145331 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设计语言都设计了专门的API实现这些功能,程序员只需要调用即可. 网络编程步骤: 1. 建立网络连接 客户端网络编程的第一步都是建立网络连接.在建立网络连接时需要指定连接到的服务器的IP地址和端口号,建立完成以后,会形成一条虚

20145239杜文超 《Java程序设计》第10周学习总结

20145239 <Java程序设计>第10周学习总结 教材学习内容总结 Java的网络编程 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据. 网络概述 1.计算机网络概述 (1)路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控制等,通过光纤.网线等连接将设备连接起来,从而形成了一张巨大的计算机网络. (2)网络最主要的优势在于共享:共享设备和数据,现在共享设备最常见的是打印机. (3)IP地址:为了能够方便的识别网络上的每个设备,网络中的每个设备

2017面向对象程序设计(Java)第二周学习总结

2017面向对象程序设计(Java)第二周学习总结 直系学妹学弟们好!额...不要问我为什么把学妹放前面,我也不知道!我只是你们和蔼可亲的学长一枚而已.也不要问为什么是第二周学习总结而不是第一周,因为第一周学长正在家里吃西瓜吹空调.好了,闲言少叙.我先为你们介绍一下助教的职责,而后再对你们的学习情况进行总结! 身为你们本学期Java课程的助教...之一,我的任务是:指导你们学习,批改我所负责学习小组的实验作业.阅读博文并回复.其他学习小组会有另外三位助教负责.由于我们每周五都会汇总你们的情况,其

第10周学习总结

20145339顿珠达杰 Java第10周学习总结 教材学习内容总结 网络编程 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 计算机网络 路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控制等,通过光纤.网线等连接将设备连接起来,从而形成了一张巨大的计算机网络. 共享 网络最主要的优势在于共享:共享设备和数据,现在共享设备最常见的是打印机. IP地址 对于网络编程来说,最主要的是计算机和计算机之间的通信,这样首要的问题就是如何找到网络上的计算机呢?这就需

20145317《信息安全系统设计基础》第10周学习总结1

20145317<信息安全系统设计基础>第10周学习总结1 第八章 异常控制流 异常 异常是控制流中的突变,用来响应处理器状态中的某些变化. 异常处理 异常号:一些是有处理器的设计者分配(包括被零除.缺页.存储器访问违例.断电及算数溢出)其他由操作系统内核的设计者分配(包括系统调用和来自外部I/O设备的信号). 异常号是到异常表中的索引. 异常与过程调用的区别(P482) 异常分为四类:中断.陷阱.故障和终止. 只有中断是异步发生的,其余三个是同步发生的 陷阱最重要的用途是在用户程序和内核之间