简体   繁体   English

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

[英]redirecting output of server to client-socket

I'm going through the socket programming and implemented it well.. Now i want to implement a system call ls in it.. 我正在通过套接字编程并很好地实现它。现在我想在其中实现一个系统调用ls ..

when the input is given as ls on the client machine , the output of the server should be printed on client machine (ie the command should execute on the server side and the output should be redirected to the client side..) 当输入在客户端机器上以ls给出时,服务器的输出应该打印在客户机上(即命令应该在服务器端执行,输出应该重定向到客户端..)

How do i collect the output of server machine? 我如何收集服务器机器的输出?

i just need hint.. Thanks 我只需要提示..谢谢

You can use dup2 to redirect stdout (or any other existing fd) to your socket fd. 您可以使用dup2stdout (或任何其他现有的fd)重定向到套接字fd。 Example: 例:

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

This should do the trick :-) 这应该做的伎俩:-)

EDIT 1 The example below shows a client program that connects to 127.0.0.1:1234, spawns a shell process, and redirects IO so that all communication is handled automatically by the shell for you. 编辑1下面的示例显示连接到127.0.0.1:1234的客户端程序,生成一个shell进程,并重定向IO,以便shell自动处理所有通信。 You can test it by running netcat -l 1234 in another terminal, then run the program and send a command like ls from netcat. 您可以通过在另一个终端中运行netcat -l 1234来测试它,然后运行该程序并从netcat发送命令,如ls Adapting it to work on the server-side is left as exercise. 将其调整为在服务器端工作仍然是练习。

IMPORTANT : This program gives unauthenticated access to the machine's 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;
}

create the empty file like cat > file and ctrl+d the filename is file 创建像cat> file这样的空文件,然后按ctrl + d创建文件名是file

client: 客户:

Get the Input from the user 从用户获取输入

ls

n=send(sockfd, msg, 1000,0); n =发送(sockfd,msg,1000,0); //msg contains the ls // msg包含ls

send function using send the message to the server 使用发送消息发送功能到服务器

Server: 服务器:

Receive function using receive the client message 使用接收客户端消息接收功能

n=receive(sockfd, msg, 1000,0); 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);
          }

Again server send the buffer to the clientfd so the output redirected to client. 服务器再次将缓冲区发送到clientfd,以便将输出重定向到客户端。

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

Finally client receive the output of command 最后客户端收到命令的输出

If I understood the question correctly, my "hint" would be to use the following: 如果我正确理解了这个问题,我的“提示”就是使用以下内容:

  1. Use popen() to execute the ls command on the server. 使用popen()在服务器上执行ls命令。
  2. Get the FILE * streams fd with fileno() . 使用fileno()获取FILE * streams fd。
  3. Use sendfile() to copy it to the client_fd. 使用sendfile()将其复制到client_fd。

Edit : sendfile() is non-standard and might not be portable. 编辑sendfile()是非标准的,可能不是可移植的。 You can replace it with a read-write loop (reading the FILE * writing into client_fd), if you want, but its more work. 如果需要,可以用读写循环(读取FILE *写入client_fd)替换它,但更多的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM