zoukankan      html  css  js  c++  java
  • TinyHttp前置知识

    (一)CGI

    CGI相关概念

    CGI:通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。

    组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行在服务器上的cgi程序。

    对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。

    get方法

    当使用这种方法时,CGI程序从环境变量QUERY_STRING获取数据。
    QUERY_STRING 被称为环境变量,就是这种环境变量把客户端的数据传给服务器。为了解释和执行程序,CGI必须要分析(处理)此字符串。当你想从服务器获得数据并且不改变服务 器上的数据时,你应该选用GET。

    post方法

    客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。

    (二)pipe管道

    管道概念

    一种基本的IPC(Inter-Process Communication 进程间通信)机制。作用于有亲缘关系的进程之间,完成数据传递。
    1.实质是一个缓冲区。

    2.两个文件描述符引用,一个表示读端,一个表示写端。数据从管道的写端流入管道,从读端流出。

    单进程管道

    父子进程管道

    图源:https://blog.csdn.net/qq_34144916/article/details/81184434

    若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。

    调用pipe系统函数即可创建一个管道。

    补充:进程间通信方式
    1. 管道pipe(也有叫做匿名管道):是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

    2. 命名管道FIFO:也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

    3. 高级管道popen:将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。

    4. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

    5. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

    6. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

    7. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

    8. 信号sinal: 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

    pipe()函数

    int pipe(int fd[2]);
    函数说明:创建一个管道,以实现进程间的通信。

    参数:数组包含pipe使用的两个文件的描述符。(一个大小为2的一个数组类型的指针)fd[0]:读管道,fd[1]:写管道。往 fd[1] 写入的数据可以从 fd[0] 读出。并且 fd[1] 一端只能进行写操作,fd[0] 一端只能进行读操作,不能反过来使用。要实现双向数据传输,可以使用两个管道。

    返回值:成功时返回0,并将一对打开的文件描述符值填入fd参数指向的数组。失败时返回 -1并设置errno。

    注意:必须在fork()中调用pipe(),否则子进程不会继承文件描述符。两个进程不共享祖先进程,就不能使用pipe。但是可以使用命名管道。

    (三)一些概念以及函数解释

    stdin,stdout和stderr

    这3个可以称为终端(Terminal)的标准输入(standard input),标准输出( standard out)和标准错误输出(standard error)。

    输入重定向:关闭标准输入设备,打开(或复制)某普通文件,使其文件描述符为0。

    输出重定向:关闭标准输出设备,打开(或复制)某普通文件,使其文件描述符为1。

    错误输出重定向:关闭标准错误输入设备,打开(或复制)某普通文件,使其文件描述符为2。

    getenv()函数

    char *getenv(char *envvar);
    函数说明:getenv()用来取得参数envvar环境变量的内容。

    参数:envvar为环境变量的名称,如果该变量存在则会返回指向该内容的指针。环境变量的格式为envvar=value。getenv函数的返回值存储在一个全局二维数组里,当你再次使用getenv函数时不用担心会覆盖上次的调用结果。

    返回值: 执行成功则返回指向该内容的指针,找不到符合的环境变量名称则返回NULL。如果变量存在但无关联值,它将运行成功并返回一个空字符串,即该字符的第一个字节是null。

    atoi()函数

    int atoi(const char *str)
    函数说明:把字符串转换成整型数。

    参数:str为要转换为整数的字符串。

    返回值:该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。

    dup()和dup2()函数

    int dup(int oldfd);

    函数说明:dup()用来复制参数oldfd 所指的文件描述符, 并将它返回. 此新的文件描述词和参数oldfd 指的是同一个文件, 共享所有的锁定、读写位置和各项权限或旗标。例如, 当利用lseek()对某个文件描述符作用时, 另一个文件描述符的读写位置也会随着改变. 不过, 文件描述符之间并不共享close-on-exec 旗标。

    返回值:当复制成功时, 则返回最小并且尚未使用的文件描述符.。若有错误则返回-1, errno 会存放错误代码。

    int dup2(int oldfd,int newfd);

    dup2()用来复制参数oldfd 所指的文件描述符, 并将它拷贝至参数newfd 后一块返回。 若参数newfd为一已打开的文件描述符, 则newfd 所指的文件会先被关闭。dup2()所复制的文件描述符, 与原来的文件描述符共享各种文件状态, 详情可参考dup()。

    返回值:当复制成功时, 则返回最小并且尚未使用的文件描述符。若有错误则返回-1, errno 会存放错误代码。

    sprintf()函数

    int sprintf(char *str, const char *format, ...);
    函数说明:发送格式化输出到 str 所指向的字符串。

    参数:str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。
    format -- 这是字符串,包含了要被写入到字符串 str 的文本。

    返回值:如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。

    wait()和waitpid()函数

    pid_t wait (int * status);
    函数说明:暂时停止目前进程的执行, 直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束, 则wait()会立即返回子进程结束状态值。

    参数:输出型参数,获取子进程退出状态,不关心则可以设置为NULL。

    返回值:成功返回被等待进程(子进程)pid,失败返回-1。

    pid_t waitpid(pid_t pid, int * status, int options);
    函数说明:waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的wait()功能。wait()可以看作waitpid()的一个特例。

    参数:
    pid -- 欲等待的子进程识别码。pid<-1 等待进程组识别码为pid绝对值的任何子进程。pid=-1,等待任一个子进程,与wait()等效。id=0 等待进程组识别码与目前进程相同的任何子进程。pid>0,等待其进程ID与pid相等的子进程。

    status -- 调用 waitpid()时子进程已经结束,则 waitpid()会立即
    返回子进程结束状态值。 子进程的结束状态值会由参数 status 返回,
    而子进程的进程识别码也会一起返回。如果不在意结束状态值,则
    参数 status 可以设成 NULL。

    options -- 提供了一些额外的选项来控制waitpid。不想使用可以设为0。

    WNOHANG 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若结束,则返回该子进程的ID。
    
    WUNTRACED 若子进程进入暂停状态,则马上返回,但子进程的结束状态不予以理会。WIFSTOPPED(status)宏确定返回值是否对应与一个暂停子进程。
    

    返回值:成功则返回子进程pid, 失败则返回-1. 失败原因存于errno 中。

    execl()函数

    int execl(const char * path, const char * arg, ...);

    函数说明及参数:execl()用来执行参数path 字符串所代表的文件路径, 接下来的参数代表执行该文件时传递过去的argv(0),argv[1], ..., 最后一个参数必须用空指针(NULL)作结束。

    返回值:如果执行成功则函数不会返回,执行失败则直接返回-1, 失败原因存于errno 中。

    (四)参考博文

    CGI详解:http://www.360doc.com/content/18/0327/17/51484742_740649523.shtml

    linux管道pipe详解:https://blog.csdn.net/oguro/article/details/53841949

    pipe函数详解:https://blog.csdn.net/judgejames/article/details/84256340

    重定向编程 dup和dup2函数:https://blog.csdn.net/u010006102/article/details/39667875/

    进程间通信的方式——信号、管道、消息队列、共享内存:https://www.cnblogs.com/LUO77/p/5816326.html

    进程等待之wait() & waitpid():https://blog.csdn.net/dangzhangjing97/article/details/79745880

  • 相关阅读:
    数据结构-树与二叉树-思维导图
    The last packet successfully received from the server was 2,272 milliseconds ago. The last packet sent successfully to the server was 2,258 milliseconds ago.
    idea连接mysql报错Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property
    redis学习笔记
    AJAX校验注册用户名是否存在
    AJAX学习笔记
    JSON学习笔记
    JQuery基础知识学习笔记
    Filter、Listener学习笔记
    三层架构学习笔记
  • 原文地址:https://www.cnblogs.com/echobiscuit/p/12659809.html
Copyright © 2011-2022 走看看