栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用popen()通过套接字执行命令

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用popen()通过套接字执行命令

警告: 这可能(或可能不)满足您的需求,因为我在下面的更正代码中反转了客户端和服务器循环的含义。正如我在上面的评论中提到的:

像这样的应用程序的正常方向是,客户端连接到服务器,并且客户端将命令[从

stdin
]
读取到服务器[这样做
popen
]并反馈结果。就是这样
ssh
。您的方向相反。您所拥有的是您开火
sshd
并等待
ssh
连接,然后
sshd
将命令发送至
ssh
。换句话说,应切换各侧的回路。

扭转这种局面是使事情对我有意义的唯一途径。如果在您想要的用例中逆转无法正常进行,则下面的代码可能仍会为您提供一些建议。

我通过引入 标记 字符的概念来表示输出结束来解决挂起问题。我从

PPP
[点对点]协议中借用了这个概念
RS-232

标志字符只是一个给定的值(例如

0x10
),不太可能是正常数据的一部分。由于您的数据很有可能是
ascii
utf-8
,因此
0x00-0x1F
可以使用该范围内的任何[未使用]字符(即,不要使用tab,cr,换行符等)。

如果您 需要
发送标志字符(即您的数据必须是完整的二进制范围

0x00-0xFF
),我已经包括了一些实现
PPP
上面使用的转义码的数据包编码/解码例程。我编写它们,但实际上并没有钩他们。在这种情况下,该标志[和逃生]字符可以是
任意 的二进制值通常
0xFF
0xFE
分别。

为简单起见,我将双方合并为一个

.c
文件。用
-s
[first] 调用服务器。

无论如何,这是经过测试的代码[请原谅免费的样式清理]:

// inetpair/inetpair -- server/client communication#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>typedef unsigned char byte;#define BUFMAX          1024int port = 1234;int opt_svr;int opt_debug;#define FLAG 0x10#define ESC  0x11#define ESC_FLAG        0x01#define ESC_ESC         0x02#define dbgprt(_fmt...)     do {         if (opt_debug)  printf(_fmt);     } while (0)// clientintclient(void){    int sock;    struct sockaddr_in serv = { 0 };    char *cp;    char buf[BUFMAX + 1];    int nread;    int flag;    int exitflg;    sock = socket(AF_INET, SOCK_STREAM, 0);    serv.sin_family = AF_INET;    serv.sin_port = htons(port);    serv.sin_addr.s_addr = inet_addr("127.0.0.1");    connect(sock, (struct sockaddr *) &serv, sizeof(serv));    while (1) {        cp = fgets(buf,BUFMAX,stdin);        if (cp == NULL) break;        exitflg = (strcmp(buf,"exitn") == 0);        // send the command        nread = strlen(buf);        write(sock, buf, nread);        if (exitflg) break;        while (1) { dbgprt("client: PREREADn"); nread = read(sock, buf, 1024); dbgprt("client: POSTREAD nread=%dn",nread); if (nread <= 0)     break; cp = memchr(buf,FLAG,nread); flag = (cp != NULL); if (flag)     nread = cp - buf; write(1,buf,nread); if (flag)     break;        }    }    close(sock);    return 0;}// serverintserver(void){    struct sockaddr_in serv_addr = { 0 };    int sock;    int acc_sock;    char buf[BUFMAX + 1];    char command[BUFMAX + 1];    ssize_t nread;    FILE *pin;    FILE *xfin;    char *cp;    struct sockaddr_in cli_addr = { 0 };    opt_debug = ! opt_debug;    dbgprt("[+] Startingn");    sock = socket(AF_INET, SOCK_STREAM, 0);    serv_addr.sin_family = AF_INET;    serv_addr.sin_addr.s_addr = INADDR_ANY;    serv_addr.sin_port = htons(port);    bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));    listen(sock, 128);    while (1) {        socklen_t cli_addrlen = sizeof(cli_addr);        dbgprt("[+] Waiting for connectionn");        acc_sock = accept(sock,(struct sockaddr *)&cli_addr,&cli_addrlen);        dbgprt("[+] Connectedn");        xfin = fdopen(acc_sock,"r");        while (1) { dbgprt("[+] Waiting for commandn"); cp = fgets(buf,BUFMAX,xfin); if (cp == NULL)     break; cp = strchr(buf,'n'); if (cp != NULL)     *cp = 0; dbgprt("[+] Command '%s'n",buf); if (strcmp(buf,"exit") == 0)     break; pin = popen(buf, "r"); while (1) {     cp = fgets(command, BUFMAX, pin);     if (cp == NULL)         break;     nread = strlen(command);     write(acc_sock, command, nread); } pclose(pin); command[0] = FLAG; write(acc_sock,command,1);        }        fclose(xfin);        close(acc_sock);        dbgprt("[+] Disconnectn");    }}// packet_enpre -- enpre packet// RETURNS: (outlen << 1)intpacket_enpre(void *dst,const void *src,int srclen){    const byte *sp = src;    byte *dp = dst;    const byte *ep;    byte chr;    int dstlen;    // enpre packet in manner similar to PPP (point-to-point) protocol does    // over RS-232 line    ep = sp + srclen;    for (;  sp < ep;  ++sp) {        chr = *sp;        switch (chr) {        case FLAG: *dp++ = ESC; *dp++ = ESC_FLAG; break;        case ESC: *dp++ = ESC; *dp++ = ESC_ESC; break;        default: *dp++ = chr; break;        }    }    dstlen = dp - (byte *) dst;    dstlen <<= 1;    return dstlen;}// packet_depre -- depre packet// RETURNS: (outlen << 1) | flagintpacket_depre(void *dst,const void *src,int srclen){    const byte *sp = src;    byte *dp = dst;    const byte *ep;    byte chr;    int flag;    int dstlen;    // depre packet in manner similar to PPP (point-to-point) protocol does    // over RS-232 line    ep = sp + srclen;    flag = 0;    while (sp < ep) {        chr = *sp++;        flag = (chr == FLAG);        if (flag) break;        switch (chr) {        case ESC: chr = *sp++; switch (chr) { case ESC_FLAG:     *dp++ = FLAG;     break; case ESC_ESC:     *dp++ = ESC;     break; } break;        default: *dp++ = chr; break;        }    }    dstlen = dp - (byte *) dst;    dstlen <<= 1;    if (flag)        dstlen |= 0x01;    return dstlen;}intmain(int argc, char **argv){    char *cp;    --argc;    ++argv;    for (;  argc > 0;  --argc, ++argv) {        cp = *argv;        if (*cp != '-') break;        switch (cp[1]) {        case 'd': opt_debug = 1; break;        case 'P': port = atoi(cp + 2); break;        case 's': opt_svr = 1; break;        }    }    if (opt_svr)        server();    else        client();    return 0;}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/381934.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号