2016-09-03 2 views
-1

Я пытаюсь реализовать базовую программу клиент-сервер ftp. Клиент должен иметь возможность подключаться к серверу и перемещаться по ним, используя команды cd и ls. Мне было интересно, как я могу написать вывод команды exec в окно оболочки клиента. Я думал о копировании вывода в файл и затем отправке его клиенту, но я ищу что-то более элегантное. Это код, который я написал, который выводит команду на оболочку сервера.Как написать вывод команды оболочки в сокет в c?

server.cpp

if(strcmp(command[0],"cd")==0) 
    chdir(command[1]); 

    pid=fork(); 

    if(pid==0){ 

    if(strcmp(command[0],"cd")==0){ 
     cout<<"Changed working directory to: "; 
     printf("%s\n",command[1]); 
     cout<<"Contents of working directory:\n"; 
     execl("/bin/ls","ls",NULL); 
    } 
    if(strcmp(command[0],"ls")==0){ 
     cout<<"Contents of working directory:\n"; 
     execl("/bin/ls","ls",command[1],NULL); 
    } 
    else if(strcmp(command[0],"chmod")==0){ 
     cout<<"Changed permissions of "; 
     printf("%s",command[2]); 
     cout<<" to "; 
     printf("%s\n",command[1]); 
     execl("/bin/chmod","chmod",command[1],command[2],NULL); 
    } 
    exit(0); 
    } 
    if(pid > 0) 
    wait(NULL); 

Как я могу получить его в клиентской оболочке? Заранее спасибо!

+0

Это не C. – Olaf

+0

Вместо того, чтобы порождать дочерние процессы, чтобы делать эти вещи, вам было бы лучше просто реализовать их самостоятельно в том же процессе. Например, вместо того, чтобы отменить подкласс chmod, вызовите системную функцию chmod() (как описано в «man 2 chmod»). Вместо того, чтобы отменить дочерний процесс «ls», вызовите opendir()/readdir()/closedir(), чтобы сгенерировать текст самостоятельно. Вместо того, чтобы отменить подпроцесс «cd», вызовите chdir(). И т. Д. –

+0

Это хорошее предложение, но будет ли оно работать с флагами, такими как «ls-a» или «ls-l»? – joe2982

ответ

1

К этому моменту ваш сервер установил соединение сокета с клиентом.

После fork(), но до exec(), dup() сокета в файл с дескриптором 1, стандартный вывод, перед тем exec() ИНГАМИ внешней команды. Поскольку его стандартный вывод будет подключен к сокету, клиент получит выход.

Вы также должны указать close() все дескрипторы файлов сокетов, перед exec(), чтобы дочерний процесс не наследовал их. Это не будет иметь никакого реального вреда в случае ls, но это ожидаемая практика.

+0

Не влияет ли это на процесс проектирования соединений? не является субоптимальным? – Myst

+0

Я не жалуюсь, я знаю, что они начали его ;-) – Myst

+0

Вы начинаете новый процесс для команды 'ls'. Независимо от того, запускает ли ваш основной серверный процесс собственный подпроцесс для каждого соединения, или же процесс основного сервера обрабатывает все одновременные соединения, не является фактором (за исключением деталей закрытия всех сокетов клиента перед дочерним процессом 'exec' 'ls'). –

Смежные вопросы