c - 为什么只有在重定向之前调用了 printf 才能使用 dup2 重定向到标准输出

标签 c printf stdout dup2

我正在尝试编写一个程序,连接到在另一个终端上使用 nc -v -l 1337 打开的服务器,并将 stdin、stdout、stderr 重定向到套接字。 意思是,另一个终端将写入套接字,我的程序将使用 getchar() 读取它并使用 printf() 响应。

我遇到了一些奇怪的事情 - 如果我注释掉 printf 的第一次使用(在 dup2(sockfd,1) 之前),一切正常。如果不是,则打印不执行任何操作。什么会导致这个?

int main() 
{ 
    int sockfd, connfd; 
    struct sockaddr_in servaddr, cli; 

    // socket create and varification 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    bzero(&servaddr, sizeof(servaddr)); 

    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    servaddr.sin_port = htons(1337); 

    connect(sockfd, (SA*)&servaddr, sizeof(servaddr));
    dup2(sockfd,0);
//---------------------------
//  printf("%s\n","hi" );
//---------------------------
    dup2(sockfd,1);
    dup2(sockfd,2);

    char buff[80]; 
    int n; 
    while(1){
        n = 0;
        while ((buff[n++] = getchar()) != '\n');
        buff[n-1] = 0;
        printf("message %s excepted\n",buff ); 
    }
    // close the socket 
    close(sockfd); 
} 

最佳答案

修复:

您需要告诉您的程序在写入时刷新 stdout:

    while(1){
        n = 0;
        while ((buff[n++] = getchar()) != '\n');
        buff[n-1] = 0;
        printf("message %s excepted\n",buff ); 

        /* ask the system to flush stdout */
        fflush(stdout);
    }

原因:(我只是猜测)

并非所有的 FILE 流都被缓冲相同。

当要打印 \n 时,连接到终端的文件流将被刷新。

当缓冲区已满时,连接到套接字的文件流将被刷新。

通过在 dup2(); 之前调用 printf("...\n");,您可以强制执行第一个行为。

关于c - 为什么只有在重定向之前调用了 printf 才能使用 dup2 重定向到标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55569173/

相关文章:

ruby - 禁用将输出放入 RSpec

c - 在 MSG_DONTWAIT 模式下使用 recvfrom() 从原始套接字读取以太网数据包

c - 如何使用 DBL_EPSILON 比较 float 的两个比率?

c - 信号量术语

带有 N 个前导零的 C printf

linux - Linux 中的 printf 问题

python - 将标准输出重定向到 tkinter 文本小部件

python - 如何使用 python 提取推送到标准输出的数据?

ios - 从混合应用程序的 UIwebview 访问 iOS native 属性/方法

c - 当字符串的长度大于 n 时,如何打印字符串的前 n 个字节?