将服务器的输出重定向到客户端套接字

时间:2013-04-24 07:27:02

标签: c linux sockets gcc

我正在通过套接字编程并很好地实现它。现在我想在其中实现一个系统调用ls ..

客户端计算机上的输入为ls时,服务器的输出应该打印在客户端计算机上(即命令应该在服务器端执行并且输出应该重定向到客户端..)

如何收集服务器机器的输出?

我只需要提示..谢谢

3 个答案:

答案 0 :(得分:7)

您可以使用dup2stdout(或任何其他现有的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

这应该可以解决问题: - )

编辑1 下面的示例显示连接到127.0.0.1:1234的客户端程序,生成一个shell进程,并重定向IO,以便shell自动处理所有通信。您可以通过在另一个终端中运行netcat -l 1234来测试它,然后运行该程序并从netcat发送ls之类的命令。将其调整为在服务器端工作仍属于练习。

重要:此程序为计算机的shell提供未经身份验证的访问

#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;
}

答案 1 :(得分:1)

像cat&gt;一样创建空文件文件和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,以便将输出重定向到客户端。

发送(的sockfd,buf1,1000,0);

最后,客户端收到命令

的输出

答案 2 :(得分:0)

如果我正确理解了这个问题,我的“提示”就是使用以下内容:

  1. 使用popen()在服务器上执行 ls 命令。
  2. 使用fileno()获取FILE * stream fd。
  3. 使用sendfile()将其复制到client_fd。
  4. 修改sendfile()是非标准的,可能无法移植。如果需要,可以用读写循环(读取FILE *写入client_fd)替换它,但它可以更多地工作。