【问题标题】:Telnet handling wc and any command that read an input from the keyboardTelnet 处理 wc 和任何从键盘读取输入的命令
【发布时间】:2013-03-03 21:45:21
【问题描述】:

我是 UNIX 新手,也是使用 C 语言编程的新手。

我想做的是telnet 的简单实现。

我在双方(服务器和客户端)都建立了所有必需的连接。

在服务器上:我收到任何请求,我fork 一个新进程来处理它

void createProcess() {
    int pid = fork();
    if( pid == CHILD ) {
        transferHandling(s);
        close(s);
        _exit(0);
    }
}

这种处理来自客户端的命令的方法:

int transferHandling(int socket) {
    char buf[20];
    char command[1024];
    int n, pid, fd[2];
    char *shell, *ps1;
    if( checkLogin(socket) == 0 ) { // Used to check user account
        send(socket, "Login Succeeded\n", 16, 0);
        if( setupENV(info->name) == 0 ) {  // setuid and setgid for the user
            if( pipe(fd) == ERROR ) {
                send(socket, "Server Busy\n", 12, 0);
                return 1;
            }
                    // Here I make a process to run the default shell for the user
                    // and make pipe between them
            if((pid = fork()) > 0) {
                dup2(fd[0], STDOUT_FILENO);
                close(fd[1]);

                //read commands from socket
                while(1) {
                    n = recv(socket, command, 1024, 0);
                                    // send the commands received to the child which contains the default shell
                    write(fd[0], command, n);
                }
            } else {
                dup2(fd[1], STDIN_FILENO);
                dup2(socket, STDOUT_FILENO);
                dup2(socket, STDERR_FILENO);
                close(fd[0]);

                //run default shell
                shell = getpwnam(info->name)->pw_shell;
                execlp(shell, shell, NULL);
            }
        } else {
            return 1; // setup ENV error
        }
    } else {
        send(socket, "Login Failed\n", 13, 0);
    }
}

这个程序可以使用任何命令成功运行,但是当客户端编写任何命令时,例如:wc, cd, bash (to run any other shell)。程序挂了。

这是建立连接后的客户端。

if(login(soc)) { // send the user information for the server
        char cmd[2024], cc[1024];
        int n;
        while(1) {
            printf("Reading\n");
            write(1, "username@hostname> ", 19);
            n = read(0, cmd, 2024);  // read the command from the STDIN, and send it to server
            send(soc, cmd, n, 0);

            printf("Receiving Now\n");
            n = recv(soc, cmd, 2024, 0); // getting back the command output
            write(1, cmd, n);
        }
    }

【问题讨论】:

    标签: c unix telnet systems-programming unix-socket


    【解决方案1】:

    您的管道文件描述符错误。你应该:

    write(fd[1], ...);
    

    和:

    dup2(fd[0], STDIN_FILENO);
    

    顺便说一句,中间进程不需要从套接字读取命令并通过管道将它们发送到外壳。您可以直接从套接字重定向 shell 的输入。此外,如果直接写入管道,则不需要dup2()。最后,执行此操作的无限循环似乎是一个非常糟糕的主意,因为它会在 shell 死亡时旋转。

    【讨论】:

    • 你的意思是,我应该删除fork() 并使dup2(socket, STDIN_FILENO) 和输出相同,然后exec 成为用户的默认shell
    • 是的。在createProcess() 中调用一次fork() 就可以了。
    • dosent' 工作,dup2(socket, STDIN_FILENO); dup2(套接字,STDOUT_FILENO); dup2(套接字,STDERR_FILENO); //关闭(fd[0]); //运行默认shell shell = getpwnam(info->name)->pw_shell; execlp(shell, shell, NULL);
    • 重定向应该没问题。你确定这不是登录程序?尝试将其注释掉并使用nc 作为客户端。此外,当stdin 已被重定向时,shell 不应提示输入命令,但仍然有效。
    猜你喜欢
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2014-09-18
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多