Перенаправление вывода с сервера на клиент - PullRequest
0 голосов
/ 17 ноября 2018

Я хочу перенаправить вывод команды (выполненной с помощью exec) в сокет, чтобы я мог читать с клиента и записывать его на стандартный вывод клиента. Я использовал dup2 () перед exec и читал из сокета, но я не знаю, когда сказать клиенту прекратить чтение, поэтому он ждет других байтов.

Это код (Вы можете найти в 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);
}
...