dup函数和dup2函数

Posted qq_34132502

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dup函数和dup2函数相关的知识,希望对你有一定的参考价值。

有时我们希望把标准输入重定向到一个文件,或者把标准输出重定向到一个网络连接(比如CGI编程),可以通过复制文件描述符函数dupdup2实现:

#include <unistd.h>
int dup(int file_descriptor);
int dup2(int file_descriptor1, int file_descriptor2);

如下实现了一个基本的CGI服务器:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <libgen.h>

#define BACKLOG     5

int main(int argc, char* argv[]) {
    if (argc <= 2) {
        printf("usage: %s ip_address port_number\\n", basename(argv[0]));
        return 1;
    }
    const char* ip = argv[1];
    int port = atoi(argv[2]);

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

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    assert(sock >= 0);

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

    ret = listen(sock, BACKLOG);
    assert(ret != -1);

    struct sockaddr_in client;
    client.sin_family = AF_INET;
    socklen_t client_addrlength= sizeof(client);
    int connfd = accept(sock, (struct sockaddr*)&client, &client_addrlength);
    if (connfd < 0) {
        printf("errno is: %d\\n", errno);
    } else {
        close(STDOUT_FILENO);
        dup(connfd);
        printf("abcd\\n");
        close(connfd);
    }

    close(sock);
    return 0;
}

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

以上是关于dup函数和dup2函数的主要内容,如果未能解决你的问题,请参考以下文章

dup/dup2

dup函数和dup2函数

dup和dup2函数

Linux dup dup2函数理解

dup和dup2函数

dup与dup2函数