将输出从服务器重定向到客户端

时间:2018-11-17 12:01:48

标签: c linux unix client-server io-redirection

我想将命令的输出(使用exec执行)重定向到套接字,以便我可以从客户端读取并将其写入客户端的标准输出。我在exec之前使用了dup2()并从套接字读取,但是我不知道何时告诉客户端停止读取,因此它正在等待其他字节。

这是代码(您可以在client.c中找到问题所在的注释)。

编辑:我自己找到了解决方案,客户端仍在等待读取其他字节,因为在父服务器进程中套接字描述符仍处于打开状态,只需要关闭它即可。

server.c

#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <stdio.h>

int main(int argc, char *argv[]){
    int sd,sd2,n1,n2;
    char message[100];
    pid_t pid;
    struct sockaddr_in my_addr;

    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(5200);
    my_addr.sin_addr.s_addr=htonl(INADDR_ANY);

    sd=socket(PF_INET,SOCK_STREAM,0);
    if(sd<0){
        write(STDOUT_FILENO,"Socket error\n",strlen("Socket error\n"));
        exit(1);
    }
    if(bind(sd,(struct sockaddr *)&my_addr,sizeof(my_addr))<0){
        write(STDOUT_FILENO,"Bind error\n",strlen("Bind error\n"));
        exit(1);
    }
    if(listen(sd,5)<0){
        write(STDOUT_FILENO,"Listen error\n",strlen("Listen error\n"));
        exit(1);
    }
    while(1){
        sd2=accept(sd,NULL,NULL);
        if(sd2<0){
            write(STDOUT_FILENO,"Accept error\n",strlen("Accept error\n"));
            exit(1);
        }
        if((pid=fork())==0){
            while(read(sd2,&n1,sizeof(int))!=0){
                n2=ntohl(n1);
                read(sd2,message,n2);
                message[n2]='\0';
                if(strcmp(message,"EXIT")==0){
                    break;
                }else if(strcmp(message,"SH")==0){

                }else if(strcmp(message,"FS")==0){
                    dup2(sd2,STDOUT_FILENO);
                    execl("/bin/df","df",(char *)NULL);
                }else{
                    //do nothing
                }
            }
            write(STDOUT_FILENO,"Server-child terminated\n",strlen("Server-child terminated\n"));
            close(sd2);
            exit(0);
        }
        close(sd2); // ADD THIS
    }
}

client.c

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

int main(int argc, char *argv[]){
    int sd,n1,n2;
    char message[100];
    struct sockaddr_in server_addr;

    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(5200);
    inet_aton("127.0.0.1",&server_addr.sin_addr);

    sd=socket(PF_INET,SOCK_STREAM,0);
    if(sd<0){
        write(STDOUT_FILENO,"Client Socket error\n",strlen("Client Socket error\n"));
        exit(1);
    }
    if(connect(sd,(struct sockaddr *)&server_addr,sizeof(server_addr))<0){
        write(STDOUT_FILENO,"Connect error\n",strlen("Connect error\n"));
        exit(1);
    }

    while(1){
        n1=read(STDIN_FILENO,&message,100);
        n1=n1-1;
        message[n1]='\0';
        n2=htonl(n1);
        write(sd,&n2,sizeof(int));
        write(sd,message,n1);
        if(strcmp(message,"EXIT")==0){
            break;
        }else if(strcmp(message,"SH")==0){

        }else if(strcmp(message,"FS")==0){
            while((n1=read(sd,message,99))!=0){ // Here is the problem
                message[n1]='\0';
                write(STDOUT_FILENO,message,strlen(message));
            }
        }else{
            //do nothing
        }

    }
    write(STDOUT_FILENO,"Client terminated\n",strlen("Client terminated\n"));
    close(sd);
    exit(0);
}

0 个答案:

没有答案