linux 反向 远程,用socket编写的linux反向远程管理程序(c/s模式)

用socket编写的linux反向远程管理程序(c/s模式)

这是我第一个正式写的linux程序,对我来说很有纪念意义。

程序主要是通过socket实现客户端连接到服务器端,然后服务器端可以控制客户端传递运行。

适用于客户端处于内网,服务器为公网的环境。其中使用了select函数实现并发连接。

源代码如下:

server.c:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXLINE 2048

#define BACKLOG 20

int

main(int argc, char **argv)

{

int   i, j,maxi, maxfd, listenfd, connfd, sockfd,len,id;

int   nready, client[FD_SETSIZE];

ssize_t   n;

fd_set   rset, allset;

char   line[MAXLINE],temp[INET_ADDRSTRLEN];

socklen_t  clilen,templen;

struct sockaddr_in cliaddr, servaddr,tempaddr;

char    buf[20],cmd[20];

if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0))<0 )

{

perror("socket");

}

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port =htons(1234);

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

{

perror("bind");

exit(1);

}

/* how we can get the binded socket information */

templen = sizeof(struct sockaddr);

if (getsockname(listenfd, (struct sockaddr *)&tempaddr,&templen) == -1){

perror("getsockname");

exit(1);

}

printf("Server is listening on port %d/n",ntohs(tempaddr.sin_port));

if (listen(listenfd,BACKLOG) == -1){

perror("listen");

exit(1);

}

maxfd = listenfd;   /* initialize */

maxi = -1;    /* index into client[] array */

for (i = 0; i < FD_SETSIZE; i++)

client[i] = -1;   /* -1 indicates available entry */

FD_ZERO(&allset);

FD_SET(listenfd, &allset);

FD_SET(0, &allset);

//maxfd = 0;

for ( ; ; ) {

rset = allset;  /* structure assignment */

nready = select(maxfd+1, &rset, NULL, NULL, NULL);

if (nready == -1) {

printf("exit! select error! %s", strerror(errno));

break;

}

if (FD_ISSET(listenfd, &rset)) { /* new client connection */

clilen = sizeof(cliaddr);

if ( ( connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen) )

{

perror("accept");

}

printf("A new connect from: %s, port %d/n",

inet_ntop(AF_INET, &cliaddr.sin_addr, temp, INET_ADDRSTRLEN),ntohs(cliaddr.sin_port));

printf("input id and cmd like: id cmd/n");

for (i = 0; i < FD_SETSIZE; i++)

if (client[i] < 0) {

client[i] = connfd; /* save descriptor */

break;

}

if (i == FD_SETSIZE)

perror("too many clients");

FD_SET(connfd, &allset); /* add new descriptor to set */

if (connfd > maxfd)

maxfd = connfd;   /* for select */

if (i > maxi)

maxi = i;    /* max index in client[] array */

if (--nready <= 0)

continue;    /* no more readable descriptors */

}

for (i = 0; i <= maxi; i++) { /* check all clients for data */

if ( (sockfd = client[i]) < 0)

continue;

if (FD_ISSET(sockfd, &rset)) {

//n = read(sockfd, line, MAXLINE);

if ( (n = read(sockfd, line, MAXLINE)) <= 0) {

//if(n==0){

/*4connection closed by client */

close(sockfd);

FD_CLR(sockfd, &allset);

client[i] = -1;

printf("client %d exited!/n",i);

}else  {

printf("%s/n",line);

printf("from ID %d/n",i);

fflush(stdout);

}

bzero(line,MAXLINE);

if (--nready <= 0)

break;    /* no more readable descriptors */

}

}

if (FD_ISSET(0, &rset)) {

/* 用户按键了,则读取用户输入的内容发送出去 */

bzero(buf, MAXLINE + 1);

fgets(buf, MAXLINE, stdin);

id=atoi(buf);

for(j=0;buf[j+1]!='/n';j++)

cmd[j]=buf[j+2];

for(j=0;(j<=maxi)&&((sockfd=client[j])>=0);j++)

{

if(j==id)

{

len =write(sockfd,cmd,strlen(cmd));

//bzero(cmd,sizeof(cmd));

if (len > 0)

printf("send %s command to ID %d/n",cmd, id);

else {

printf("send %s error!/n",buf);

break;

}

bzero(cmd,sizeof(cmd));

}

}

}

}

}

client.c:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXLINE 4096

char sendhead[MAXLINE];

int main(int argc , char* argv[])

{

int sockfd;

struct sockaddr_in servaddr;

char *info="client number 1 ";

char *sys_err="system error!/n";

char *first="pid/tppid/t/tcmd/n";

int   maxfdp1, stdineof;

fd_set  rset;

char  recvbuf[20],tmp[128],buffer[MAXLINE];

int             n,len,fd;

FILE   *ff;

if(argc!=3){

printf("useage:client address port ");

exit(0);

}

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1  )

{

perror("socket");

exit(1);

}

printf("%s connect server/n",info);

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family=AF_INET;

servaddr.sin_port=htons(atoi(argv[2]));

inet_pton(AF_INET,argv[1],&servaddr.sin_addr);

if( ( connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))  )<0)

{

perror("connect");

exit(1);

}

write(sockfd,info,strlen(info));

FD_ZERO(&rset);

for ( ; ; ) {

FD_SET(sockfd, &rset);

maxfdp1=sockfd+1;

if(  ( select(maxfdp1, &rset, NULL, NULL, NULL) )<0)

{

perror("select");

}

if (FD_ISSET(sockfd, &rset)) { /* socket is readable */

bzero(recvbuf,20);

n=read(sockfd, recvbuf, 20) ;

if(n<0) {

perror("str_cli: server terminated prematurely");

}else if(n==0)

{

printf("sever shutdown!");

exit(-1);

}

printf("receive cmd:%s/n",recvbuf);

write(sockfd,info,strlen(info));

bzero(buffer,MAXLINE);

ff=popen(recvbuf,"r");

fread(buffer,sizeof(char),MAXLINE,ff);

write(sockfd,buffer,strlen(buffer));

//printf("%s",buffer);

bzero(buffer,MAXLINE);

}

}

exit(0);

}

其实这就是个简单的telnet程序,不过是反向连接的,linux的ssh也可以实现反向连接。

方法如下:

例如一部linux在内网,一部在公网,

在内网上执行: ssh -f -N -R 8888:localhost:22 xxx@xxx.xxx.org , xxx.xxx.org可以是ip,

在公网的的电脑上执行: ssh xxxx@localhost -p 8888 就可以成功连上内网的电脑了,

上面命令里面的 8888 是任一个本地端口。

参考文章:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值