最火下载站首页
手机版
最火下载站
关注公众号
最火下载站

当前位置:首页 > 网络知识 > 网络技术 > Linux> Linux实例:用socket通讯远程执行命令

Linux实例:用socket通讯远程执行命令

文章作者:网友投稿 发布时间:2008-12-20 来源:网络

以下为引用的内容:
服务器端程序:
/**********************************************************
* server.c
* 服务器端程序
*
*********************************************************/
#include
#include
#include
#include
#include
#include
#include
#include

#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          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      i++;

    pclose(fp);
  }
  return i;
}
#p#副标题#e#
以下为引用的内容:
以下是客户端程序!
/***************************************************
* client.c
* 在Red Hat 9.0 GCC下调试通过!
* 在运行服务器端程序之后,
* 再运行客户端,否则,连接会失败!
* ./client 你的ip地址 [端口]
* 呵呵!!
* GoodLuck
***************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#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;
}

上一篇: Linux系统管理员成长经验:十一个心得

下一篇: Linux操作系统下FrameBuffer直接写屏

共有0条评论网友评论

游戏排行榜