实现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
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129711.html