linux高性能服务器高级IO之实验(9)

实现CGL服务器

CGI 是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。
CGI(Common Gateway Interface) 是WWW技术中最重要的技术之一,有着不可替代的重要地位。CGI是外部应用程序(CGI程序)与WEB服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的过程。
CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体。

CGI的处理步骤:

通过Internet把用户请求送到web服务器。
web服务器接收用户请求并交给CGI程序处理。
CGI程序把处理结果传送给web服务器。
web服务器把结果送回到用户。

#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<libgen.h>
#include<assert.h>
int main(int argc,char* argv[])
{
      if(argc<=2)
      {
          printf("Usage : %s ip_address port_number \n",basename(argv[0]));
          return 1;
      }
      char* ip=argv[1];
      int port=atoi(argv[2]);

      struct sockaddr_in address;
      bzero(&address,sizeof(address));
      address.sin_family=AF_INET;
      address.sin_port=htons(port);
      inet_pton(AF_INET,ip,&address.sin_addr);

      int sockfd=socket(PF_INET,SOCK_STREAM,0);
      assert(sockfd!=-1);

      int ret=bind(sockfd,(struct sockaddr*)&address,sizeof(address));
      assert(ret!=-1);

      ret=listen(sockfd,5);
      assert(ret!=-1);

      struct sockaddr_in client;
      socklen_t client_length=sizeof(client);
      int connfd=accept(sockfd,(struct sockaddr*)&client,&client_length);
      if(connfd<0)
      {
        printf("errno is %d\n",errno);
      }
      else
      {
          close(STDOUT_FILENO);
          dup(connfd);
          printf("abcd\n");
          close(connfd);
      }
      close(sockfd);
      return 0;
}

我们先关闭标准输出文件描述符STDOUT_FILENO(其值是1),然后复制socket文件描述符connfd。因为dup总是返回系统中最小的可用文件描述符,所以它的返回值实际上是1,即之前关闭的标准输出文件描述符的值。这样一来,服务器输出到标准输出的内容(这里是“abcd”)就会直接发送到与客户连接对应的socket 上,因此 printf调用的输出将被客户端获得(而不是显示在服务器程序的终端上)。这就是CGI服务器的基本工.作原理。

实现tee

Linux tee命令用于读取标准输入的数据,并将其内容输出成文件。

tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。

#include<assert.h>
#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>

int main(int argc,char* argv[])
{
    if(argc!=2)
    {
        printf("Usage %s <file>\n",argv[0]);
        return 1;

    }
    int filefd=open(argv[1],O_CREAT|O_WRONLY|O_TRUNC,0666);
    assert(filefd>0);

    int pipefd_stdout[2];
    int ret=pipe(pipefd_stdout);
    assert(ret!=-1);

    int pipefd_file[2];
    ret=pipe(pipefd_file);
    assert(ret!=-1);

    //将std——out 输入pipefd_stdout;
    ret=splice(STDIN_FILENO,NULL,pipefd_stdout[1],NULL,32768,SPLICE_F_MORE|SPLICE_F_MOVE);
    assert(ret!=-1);
    //将管道pipefd_STDOUT的输出复制到管道pipefd_file的输入端
    ret=tee(pipefd_stdout[0],pipefd_file[1],32768,SPLICE_F_NONBLOCK);
    assert(ret!=-1);
    //pipe_file的输出定向到filed
    ret=splice(pipefd_file[0],NULL,filefd,NULL,32768,SPLICE_F_MORE|SPLICE_F_MOVE);
    assert(ret!=-1);
    //将pipefd_stdout的输出定向到标准输入 其内容和输入文件内容一致
    ret=splice(pipefd_stdout[0],NULL,STDIN_FILENO,NULL,32768,SPLICE_F_MORE|SPLICE_F_MOVE);
    assert(ret!=-1);
    close(filefd);
    close(pipefd_stdout[0]);
    close(pipefd_stdout[1]);
    close(pipefd_file[1]);
    close(pipefd_file[1]);
    return 0;
        
}
[root@localhost IO_BASIC]# ./a.out test.txt 
this is a simple tee 
this is a simple tee 
[root@localhost IO_BASIC]# vim test.txt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值