程序员人生 网站导航

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

栏目:服务器时间:2014-01-23 22:23:31
以下为引用的内容:
服务器端程序:
/**********************************************************
* 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");
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'",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]!=''){
        i++;
        if(i<BUFSIZE-1)
          goto receive;
      }
      recv_buf[i]='';
      printf("receive '%s'",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'"
                          "show[route|arp|tcp|nic]",cmd2);
}else if(cn==1){
  if(strcmp(cmd1,"quit")==0)
    break;
  send_buf[0]='';
  if(strcmp(cmd1,"help")!=0)
    sprintf(send_buf,"command error '%s'",cmd1);
  strcat(send_buf,"command:"
                  "show route"
  "show arp"
  "show tcp"
  "show nic"
  "quit"
  "help");
  sn=strlen(send_buf);
}else
  sn=sprintf(send_buf,"command error '%s'",cmd1);
if(sn==0)
  sn=sprintf(send_buf,"");
 
if(send(s,send_buf,sn,0)<0)
  break;
printf("%s",send_buf);
      }
      printf("Connection closed.");
      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.",command);
  }else{
    i=0;
    while((buf[i]=fgetc(fp))!=EOF && i<bufmax-1)
      i++;

    pclose(fp);
  }
  return i;
}
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐