用socket通讯执行远程命令-linux实例

以下是客户端程序!
/***************************************************
* client.c
* 在Red Hat 9.0 GCC下调试通过!
* 在运行服务器端程序之后,
* 再运行客户端,否则,连接会失败!
* ./client 你的ip地址 [端口]
* 呵呵!!
* GoodLuck
***************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define BUFSIZE 8192
#define DEFAULT_PORT 5320

enum {SMD_NAME,DST_IP,DST_PORT};

int main(int argc,char *argv[])
{
  struct sockaddr_in server;    //服务器地址
  unsigned long dst_ip;         //服务器IP地址
  int port;     //端口号
  int s;        //套接字的描述符
  int n;        //输入数据的字节数
  char buf[BUFSIZE];    //接收缓
  char cmd[BUFSIZE];    //发送缓
  struct timeval tv;    //select超时时间
  fd_set readfd;        //使用select检索出的描述符

  //实际参数的检查
  if(argc!=2 && argc!=3){
    fprintf(stderr,"Usage: %s hostname[port]/n",argv[0]);
    exit(EXIT_FAILURE);
  }
 
  //检索服务器的ip地址
  if((dst_ip=inet_addr(argv[DST_IP]))==INADDR_NONE){
    struct hostent *he; //主机信息
   
    if((he=gethostbyname(argv[DST_IP]))==NULL){
      fprintf(stderr,"gethostbyname error/n");
      exit(EXIT_FAILURE);
    }
    memcpy((char *)&dst_ip,(char *)he->h_addr,sizeof(he->h_addr));
  }

  //检索服务器的端口号
  if(argc==3){
    if((port=atoi(argv[DST_PORT]))==0){
      struct servent * se; //服务信息
     
      if((se=getservbyname(argv[DST_PORT],"tcp"))!=NULL)
        port=(int) ntohs((u_short)se->s_port);
      else{
        fprintf(stderr,"getservbyname error/n");
        exit(EXIT_FAILURE);
      }
    }
  }else
    port=DEFAULT_PORT;
 
  //使用TCP协议打开一个套接字
  if((s=socket(AF_INET,SOCK_STREAM,0))<0){
    perror("socket");
    exit(EXIT_FAILURE);
  }
 
  //设定服务器的地址,建立一个连接
  memset((char *)&server,0,sizeof(server));
  server.sin_family=AF_INET;
  server.sin_addr.s_addr=dst_ip;
  server.sin_port=htons(port);
  if(connect(s,(struct sockaddr *)&server,sizeof(server))<0){
    perror("connect");
    exit(EXIT_FAILURE);
  }
 
  printf("Connected to '%s'/n",inet_ntoa(server.sin_addr));
 
  //客户机处理的主要子程序
  while(1){
    //select超时的设定
    tv.tv_sec=600;
    tv.tv_usec=0;
   
    //标准输入,有无来自服务器的报文
    FD_ZERO(&readfd);
    FD_SET(0,&readfd);
    FD_SET(s,&readfd);
    if((select(s+1,&readfd,NULL,NULL,&tv))<=0){
      fprintf(stderr,"/nTimeout/n");
      break;
    }
   
    //标准输入
    if(FD_ISSET(0,&readfd)){
      if((n=read(0,buf,BUFSIZE-1))<=0)
        break;
      buf[n]='/n';
      sscanf(buf,"%s",cmd);
      if(strcmp(cmd,"quit")==0)
        break;
      if(send(s,buf,n,0)<=0)
        break;
    }
   
    //服务器
    if(FD_ISSET(s,&readfd)){
      if((n=recv(s,buf,BUFSIZE-1,0))<=0){
        fprintf(stderr,"connection closed./n");
exit(EXIT_FAILURE);
      }
      buf[n]='/0';
      printf("%s",buf);
      fflush(stdout);
    }
  }
 
  strcpy(buf,"quit");
  send(s,buf,n,0);
  close(s);
 
  return EXIT_SUCCESS;
}

 

 

/*********************************************************/

 

 

 服务器端程序:
/**********************************************************
* server.c
* 服务器端程序
*
*********************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<netdb.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define BUFSIZE 8192
#define DEFAULT_PORT 5320

enum{CMD_NAME,SRC_PORT};

int execute(char *command,char *buf,int bufmax);

int main(int argc,char *argv[])
{
  struct sockaddr_in server; //服务器地址
  struct sockaddr_in client; //客户机地址
  int len; //sockaddr_in的长度
  int port; //服务器端口号
  int s; //接收报文用描述符
  int s0; //接收连接用描述符
  int cn; //接收命令的字数
  int sn; //发送报文的字节数
  int rn; //接收报文的字节数
  char cmd1[BUFSIZE]; //第一个语句命令
  char cmd2[BUFSIZE]; //第二个语句命令
  char recv_buf[BUFSIZE]; //接收缓冲区
  char send_buf[BUFSIZE]; //发送缓冲区
 
  //实际参数的处理(端口号)
  if(argc==2){
    if((port=atoi(argv[SRC_PORT]))==0){
      struct servent *se; //服务信息
     
      if((se=getservbyname(argv[SRC_PORT],"tcp"))!=NULL)
        port=(int) ntohs((u_short)se->s_port);
      else{
        fprintf(stderr,"getservbyname error/n");
exit(EXIT_FAILURE);
      }
    }
  }else
    port=DEFAULT_PORT;
     
    //使用TCP协议打开一个套接字
  if((s0=socket(AF_INET,SOCK_STREAM,0))<0){
    perror("socket");
    exit(EXIT_FAILURE);
  }
   
  //设定服务器地址
  memset((char *)&server,0,sizeof(server));
  server.sin_family=AF_INET;
  server.sin_addr.s_addr=htonl(INADDR_ANY);
  server.sin_port=htons(port);
  if(bind(s0,(struct sockaddr *)&server,sizeof(server))<0){
    perror("bind");
    exit(EXIT_FAILURE);
  }
   
  //开始接受建立连接请求
  listen(s0,5);
   
  //接收连接循环
  while(1){
  //接收连接处理
    len=sizeof(client);
    if((s=accept(s0,(struct sockaddr *)&client,&len))<0){
      perror("accept");
      exit(EXIT_FAILURE);
    }
    printf("Connected From '%s'/n",inet_ntoa(client.sin_addr));
     
#ifdef FORK_SERVER
  if(fork()!=0){
    close(s);
    continue;
  }
  close(s0);
#endif
    //服务器处理的主要子程序
    while(1){
      int i=0; //接收字符的计数器
   
      sn=sprintf(send_buf,"TCP>");
      send(s,send_buf,sn,0);
   
      receive: //流型数据的接收处理
      if((rn=recv(s,&recv_buf[i],1,0))<0)
        break;
     
      //以换行为单位进行接收处理
      if(recv_buf[i]!='/n'){
        i++;
        if(i<BUFSIZE-1)
          goto receive;
      }
      recv_buf[i]='/0';
      printf("receive '%s'/n",recv_buf);
  
      //接收命令的处理
      if((cn=sscanf(recv_buf,"%s%s",cmd1,cmd2))<=0)
        continue;
      else if(cn==2 && strcmp(cmd1,"show")==0){
        if(strcmp(cmd2,"route")==0)
#ifdef _linux
  sn=execute("/usr/bin/netstat -rn",send_buf,BUFSIZE);
#else
  sn=execute("/bin/netstat -rn",send_buf,BUFSIZE);
#endif
        else if(strcmp(cmd2,"arp")==0)
#ifdef _linux
  sn=execute("/usr/sbin/arp -an",send_buf,BUFSIZE);
#else
  sn=execute("/sbin/arp -an",send_buf,BUFSIZE);
#endif
          else if(strcmp(cmd2,"tcp")==0)
#ifdef _linux
  sn=execute("/usr/bin/netstat -tn",send_buf,BUFSIZE);
#else
  sn=execute("/bin/netstat -tn",send_buf,BUFSIZE);
#endif
            else if(strcmp(cmd2,"nic")==0)
      sn=execute("/sbin/ifconfig -a",send_buf,BUFSIZE);
    else
      sn=sprintf(send_buf,"parameter error '%s'/n"
                          "show[route|arp|tcp|nic]/n",cmd2);
}else if(cn==1){
  if(strcmp(cmd1,"quit")==0)
    break;
  send_buf[0]='/0';
  if(strcmp(cmd1,"help")!=0)
    sprintf(send_buf,"command error '%s'/n",cmd1);
  strcat(send_buf,"command:/n"
                  "show route/n"
  "show arp/n"
  "show tcp/n"
  "show nic/n"
  "quit/n"
  "help/n");
  sn=strlen(send_buf);
}else
  sn=sprintf(send_buf,"command error '%s'/n",cmd1);
if(sn==0)
  sn=sprintf(send_buf,"/n");
 
if(send(s,send_buf,sn,0)<0)
  break;
printf("%s",send_buf);
      }
      printf("Connection closed./n");
      close(s);
    }
    close(s0);
   
    return EXIT_SUCCESS;
  }
 
  /*
   *int execute(char *command,char *buf,int bufmax);
   *
   *功能
   * 执行命令,将结果存储到缓冲区中
   *实际参数
   * char *command; 所执行的命令
   * char *buf; 存储输出结果的缓冲区
   * int bufmax 缓冲区的大小
   *返回值
   * int 存储到缓冲区的字符数
   */
int execute(char *command,char *buf,int bufmax)
{
  FILE *fp; //文件指针
  int i; //输入数据的字节数
    
  if((fp=popen(command,"r"))==NULL){
    perror(command);
    i=sprintf(buf,"server error: '%s' cannot execute./n",command);
  }else{
    i=0;
    while((buf[i]=fgetc(fp))!=EOF && i<bufmax-1)
      i++;

 pclose(fp);
  }
  return i;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值