linux 远程shell,linux 远程shell 实现

实现了一个 shell server的功能,每当有客户端连接的时候,都会为远程客户端分配shell。

使用命令:

启动服务端  ./a.out server

启动客户端: ./a.out client

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

int run_shell(int cmd_pipe, int echo_pipe)

{

int pid = -1;

pid = fork();

if(pid < 0)

{

perror("fork child error\n");

return 0;

}

else if(pid == 0)

{

dup2(cmd_pipe, STDIN_FILENO);

dup2(echo_pipe, STDOUT_FILENO);

dup2(echo_pipe, STDERR_FILENO);

//system("sh");

execl("/bin/sh","/bin/sh",(char *)0);

exit(0);

return 0;

}

else

{

//waitpid(pid, 0, 0);

return pid;

}

}

const char g_end_cmd[] = "\03\n";//"^C\n"

void *client_work_thread(void *pclientfd)

{

printf("client_work_thread for connect 0x%x\n", (int)pclientfd);

int clisock = (int)pclientfd;

if(fcntl(clisock, F_SETFL, fcntl(clisock, F_GETFL) | O_NONBLOCK) == -1)

{

perror("cann't set noblock socket\n");

close(clisock);

return 0;

}

fd_setrset;

int fdpipe_send_cmd[2];

int fdpipe_recv_echo[2];

if(pipe(fdpipe_send_cmd) == -1)

{

close(clisock);

return 0;

}

if(pipe(fdpipe_recv_echo) == -1)

{

close(clisock);

close(fdpipe_send_cmd[0]);

close(fdpipe_send_cmd[1]);

return 0;

}

int fscmd = fdpipe_send_cmd[1];

int fsecho = fdpipe_recv_echo[0];

int child_pid = run_shell(fdpipe_send_cmd[0], fdpipe_recv_echo[1]);

int fdmaxp1 = (fsecho > clisock) ? (fsecho + 1) : (clisock + 1);

struct timeval tv;

tv.tv_sec = 1;

tv.tv_usec = 0;

char pipebuf[1024] = "";

while(1)

{

FD_ZERO(&rset);

FD_SET(clisock, &rset);

FD_SET(fsecho, &rset);

memset(pipebuf, 0x00, sizeof(pipebuf));

int nret = select(fdmaxp1, &rset, 0, 0, &tv);

if(nret == -1)

{

break;

}

if(FD_ISSET(fsecho, &rset))

{

read(fsecho, pipebuf, 1024);

if(send(clisock, pipebuf, strlen(pipebuf), 0) < 0)

{

perror("send error\n");

write(fscmd, g_end_cmd, sizeof(g_end_cmd));

break;

}

}

if(FD_ISSET(clisock, &rset))

{

if(recv(clisock, pipebuf, 1024, 0) <= 0)

{

perror("clisock closed\n");

write(fscmd, g_end_cmd, sizeof(g_end_cmd));

break;

}

printf("send cmd -- %s\n", pipebuf);

write(fscmd, pipebuf, strlen(pipebuf));

}

}

close(clisock);

close(fdpipe_send_cmd[0]);

close(fdpipe_send_cmd[1]);

close(fdpipe_recv_echo[0]);

close(fdpipe_recv_echo[1]);

kill(child_pid, SIGKILL);

waitpid(child_pid, 0);

return 0;

}

const unsigned short k_SERVER_PORT = 3434;

void *server_thread(void *para)

{

struct sockaddr_in servaddr;

int listenfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&servaddr, 0x00, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(k_SERVER_PORT);

if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)

{

close(listenfd);

perror("bind error\n");

return 0;

}

if(listen(listenfd, 10) == -1)

{

close(listenfd);

perror("listen error\n");

return 0;

}

printf("listen on %d\n", k_SERVER_PORT);

int clifd = -1;

pthread_t clith;

pthread_attr_t attr;

pthread_attr_init(&attr);

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

while((clifd = accept(listenfd, 0, 0)) != -1)

{

//client work thread

printf("accept new connect.\n");

pthread_create(&clith, &attr, client_work_thread, (void *)clifd);

}

pthread_attr_destroy(&attr);

}

void *client_thread(void *para)

{

struct sockaddr_in servaddr;

int clifd = socket(AF_INET, SOCK_STREAM, 0);

memset(&servaddr, 0x00, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

servaddr.sin_port = htons(k_SERVER_PORT);

if(connect(clifd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)

{

perror("connect error\n");

close(clifd);

return 0;

}

char sndbuf[1024] = "";

while(1)

{

scanf("%s", sndbuf);

strcat(sndbuf, "\n");

send(clifd, sndbuf, strlen(sndbuf), 0);

recv(clifd, sndbuf, 1024, 0);

printf(sndbuf);

}

close(clifd);

return 0;

}

int main(int argc, const char** argv)

{

if(argc == 2)

{

if(strstr(argv[1], "client"))

{

printf("start client mode\n");

client_thread(0);

}

else

{

printf("start server mode\n");

server_thread(0);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值