2013-04-24 86 views
2

我經歷了套接字編程並實現很好..現在我想實現一個系統調用ls在它..重定向服務器的輸出到客戶端,插座

當輸入給定爲ls客戶端機器上,服務器的輸出應客戶端機器上進行打印(即命令執行在服務器側和輸出應重定向到客戶端。)

我如何收集服務器機器的輸出?

我只需要提示..謝謝

回答

1

創建像貓>文件和Ctrl空文件+ d的文件名是文件

客戶端:

從用戶獲取輸入

ls 

N =發送(的sockfd,MSG ,1000,0); // MSG包含使用將消息發送到服務器的LS

發送功能

服務器:

接收使用接收的客戶端消息

N =接收函數(的sockfd,MSG,1000, 0);

 FILE *fp;  

    recvbuf[strlen(recvbuf)-1]=0; // client msg received and delete the \n 
    strcat(recvbuf,">file"); // add to redirected file 
    printf("Recvbuf:%s\n",recvbuf); // ls>file 
    int status=0; 
    pid_t pid=vfork(); 
    if(pid==0) 
    execlp("sh","sh","-c",recvbuf,(char *)0); // executed the ls command and redirected to file 
     else 
     { 
     wait(&status); 
    fp=fopen("file","r"); //open the file read the content and stored to buffer 
     while((c=getc(fp))!=EOF) 
      buf1[i++]=c; 
      buf1[i]='\0'; 
      printf("%s\n",buf1); 
      fclose(fp); 
      } 

服務器再次發送緩衝區到clientfd,以便輸出重定向到客戶端。

send(sockfd,buf1,1000,0);

終於客戶端收到命令的輸出

+0

done .. working .. :) – 2013-04-25 03:38:41

+0

雖然這需要每個客戶端的臨時文件。否則,你會看到混合輸出。 – jweyrich 2013-04-25 03:55:07

+0

父母正在等待孩子完成然後只顯示混合輸出' – loganaayahee 2013-05-09 09:05:56

5

您可以使用dup2重定向stdout(或任何其他現有的FD)到您的套接字fd。例如:

int client_fd = accept(server_fd, 0, 0); 
assert(client_fd != -1); 
close(0); // Close stdout 
dup2(client_fd, 0); // Redirect stdout to client_fd 

這應該做的伎倆:-)

EDIT 1下面的例子示出了連接到127.0.0.1:1234的客戶機程序,產生一個外殼進程,並重定向IO所以所有通信都由shell自動處理。您可以在另一個終端上運行netcat -l 1234進行測試,然後運行該程序並從netcat發送類似ls的命令。適應它在服務器端工作是作爲練習。

重要事項:該程序將未經身份驗證的訪問權授予機器的外殼。

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

int exec_shell(int sock_fd) { 
    // Redirect IO 
    dup2(sock_fd, 0); 
    dup2(sock_fd, 1); 
    dup2(sock_fd, 2); 

    // Execute shell 
    execl("/bin/sh", "sh", NULL); 

    return 0; 
} 

int main() { 
    int fd = socket(AF_INET, SOCK_STREAM, 0); 

    struct sockaddr_in sa_dst; 
    memset(&sa_dst, 0, sizeof(struct sockaddr_in)); 
    sa_dst.sin_family = AF_INET; 
    sa_dst.sin_port = htons(1234); 
    sa_dst.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    int ret = connect(fd, (struct sockaddr *)&sa_dst, sizeof(struct sockaddr)); 
    assert(ret != -1); 
    exec_shell(fd); 
    close(fd); 

    return EXIT_SUCCESS; 
} 
+0

很抱歉,我不太清楚你的解決方案會完成什麼。我認爲OP的姿勢(作業)是關於一個客戶端 - 服務器TCP系統的問題,並且多路複用標準輸入和標準輸出像一種方式流到像TCP這樣的雙工流上。 – thuovila 2013-04-24 10:30:24

+0

@thuovila:我列舉了一個例子來澄清。當然,還有其他的選擇,比如exec系列的'popen','pipe'和其他功能。 – jweyrich 2013-04-25 03:58:06

+0

好的,我現在看到它。 – thuovila 2013-04-25 07:30:04

0

如果我理解正確的問題,我的「暗示」是使用以下:

  1. 使用popen()在服務器上執行LS命令。
  2. 使用fileno()獲取FILE *流fd。使用sendfile()將其複製到client_fd。

編輯sendfile()是非標準的,可能無法移植。如果需要,可以用讀寫循環替換它(讀取FILE *寫入client_fd),但它的工作量更大。

相關問題