c/c++语言开发共享Telnet模拟系统(Linux c)

第3章详细设计和实现 第3章详细设计和实现 3.1相关技术 1)TCP编程,主要包括socket()函数、bind()函数、listen()函数、recv()函数、send()函数以及客户端的connect()函数。 2)C语言中对结构体的操作,和对字符串的比较 3)对文件的读写操作 4)popen …

3章详细设计和实现

3.1相关技术

    1tcp编程,主要包括socket()函数、bind()函数、listen()函数、recv()函数、send()函数以及客户端的connect()函数。

  2c语言中对结构体的操作,和对字符串的比较

  3)对文件的读写操作

  4popen调用shell

 

3.2开发工具和运行环境

    本系统在ubantu 16.4 lts环境下开发,所用的工具为vi编辑器和gedit编辑器,以及gcc编译工具。

 

 

3.3主要功能的源码

3.3.1服务器端socket的建立

    if ( (sockfd = socket(af_inet, sock_stream, 0)) < 0 )  //创建socket

        printf( “socket failed” );

 

    /* 设置端口快速重用*/

    optval = 1;

    if ( setsockopt(sockfd, sol_socket, so_reuseaddr, (void *)&optval, sizeof(int)) < 0 )

        printf( “setsockopt failed” );

 

    server_addr.sin_family = af_inet;

    server_addr.sin_port = htons( port );

    server_addr.sin_addr.s_addr = htonl( inaddr_any );

 

   if ( bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0 ) //绑定ip和端口号

        printf( “bind failed” );

 

    if ( listen(sockfd, max_listen) < 0 ) //建立监听

        printf( “listen failed” );

 

3.3.2对客户端的发送信息进行处理

while ( 1 ) {

    if ( (connfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_size)) < 0 ) //响应客户端请求

            printf( “accept failed” );

        printf( “server accept a client: ip = %sn”,inet_ntoa(client_addr.sin_addr) ); //打印客户端ip

        

        /* 创建子进程处理客户端请求 */

        if ( (pid = fork()) == 0 ) {

            while ( 1 ) {

                /* 接受客户端信息 */

                if ( (recv_bits = recv(connfd, buffer, buf_size, 0)) < 0 )

                    printf( “recv failed” );

 

                /* 去除最后一个字符 */

                buffer[recv_bits – 1] = ‘’;

 

                /* 用户名鉴定 */

                if ( recv_type == username ) {

                    if ( strcmp(name, buffer) != 0 ) {

                  if ( send(connfd, error_user,strlen(error_user), 0) < 0 )

                            printf( “send failed” );

break;

                    }else{

if ( send(connfd, correct_user,strlen(correct_user), 0) < 0 )

                            printf( “send failed” );

}

printf(“%s正在登录:“,buffer);

                        recv_type = password;  //设置标志为密码鉴定模式

                }

                /* 密码鉴定 */

                else if ( recv_type == password ) {

                    if ( strcmp(passwd, buffer) != 0 ) { //验证密码

                  if ( send(connfd, error_password,strlen(error_password), 0) < 0 )

                            printf( “send failed” );

                    } else {

                    if ( send(connfd, success_login, strlen(success_login), 0) < 0 )

                            printf( “send failed” );

printf(“用户登录成功!n”);

recv_type = command;  //设置标志为命令模式

                    }                

                }

/* 命令模式 */

else if( recv_type == command ) {

command(connfd,buffer);   

puts(“客户端输入的命令为:“);

puts(buffer);                 

                }

            }

            close( sockfd );

            close( connfd );

            exit ( 0 );

        }

        else

            close( connfd );

}

 3.3.3 执行命令函数

int command(int connfd,char*command)

{    

    /*

     *  作用:通过popen调用shell执行command命令

     *  connfd: 客户端标识

     *  command: 命令字符串

    */

    file *fstream = null;      

    char buff[1024];    

    memset(buff, 0, sizeof(buff));   

if ( strcmp(exit_command, command) == 0 ) { //退出

        if ( send(connfd, exit_command,strlen(exit_command), 0) < 0 )

          printf( “send failed” );

printf(“客户端已断开连接!n”);

  return 0;

    }

    if(null == (fstream = popen(command,”r”)))      

    {     

        fprintf(stderr,”execute command failed: %s”,strerror(errno));      

        return -1;      

    }   

 

    while(null != fgets(buff, sizeof(buff), fstream))

    {  

        //printf(“%s”,buff);  

if ( send(connfd, buff,strlen(buff), 0) < 0 ) //将命令执行结果发送至客户端

         printf( “send failed” );    

    }

    pclose(fstream);    

 

    return 0;     

}

3.3.4客户端发送与接受信息

int send_recv( int connfd,char flag )

{

 /*

     *  作用:客户端与服务器端信息的处理

     *  connfd: 服务器端标识

 *  flag: 输入类比标识

    */

    char input_buf[ buf_size ]; //定义字符串存放输入信息

    char recv_buf[ buf_size ]; //定义字符串存放服务器端返回信息

memset(input_buf, 0, sizeof(input_buf));

memset(recv_buf, 0, sizeof(recv_buf));

    

fgets( input_buf, buf_size, stdin ); //获取用户输入

    input_buf[strlen(input_buf) – 1] = ‘’; //去除最后一个输入的确认

 

    /* 向服务器发送消息 */

    if ( send(connfd, input_buf, buf_size, 0) < 0 )

        printf( “send failed” );

 

    /* 从服务器接受消息 */

    if ( recv(connfd, recv_buf, buf_size, 0) < 0 )

        printf( “recv failed” );

 

/* 用户名处理 */

    if ( flag == ‘u’ ) {

        if ( strcmp(recv_buf, error_user) == 0 ) {  //用户名错误

            puts( error_user );

            return false;

        }

    }

/* 密码处理 */

    else if ( flag == ‘p’ ) {

        if ( strcmp(recv_buf, error_password) == 0 )

          {  puts( error_password );  //密码错误

 return false;

}

    }

/* 命令处理 */

else if( flag == ‘c’ )

{

if ( strcmp(recv_buf, exit_command) == 0 ) {  //退出

printf(“连接已断开n”);          

return false;

     }

puts(recv_buf); //命令结果输出

}

    return true;

}

 

7章 附录

7.1服务器端

 

#include <unistd.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <assert.h>  #include <errno.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <arpa/inet.h>  #include <netinet/in.h>     #define port         3333  //用户名和密码  char *name="twain";  char *passwd="123";     #define max_listen    10  #define buf_size     1024  #define username   0  #define password   1     #define command    2     //登录过程状态标识  char *error_user = "error user name";  char *error_password = "error password";  char *correct_user = "correct user";  char *success_login = "correct password";  char *exit_command = "exit";  char *exit_tip="退出连接!";        /*  * 介绍:服务器端  * 功能:  *    1.接受客户端的登录请求并验证  *    2.接受客户端的命令在本地执行并返回执行结果  */     int command(int connfd,char*command)  {          /*       *  作用:执行command命令       *  connfd: 客户端标识       *  command: 命令字符串      */      file *fstream = null;            char buff[1024];          memset(buff, 0, sizeof(buff));     if ( strcmp(exit_command, command) == 0 ) { //退出          if ( send(connfd, exit_command,strlen(exit_command), 0) < 0 )            printf( "send failed" );  printf("客户端已断开连接!n");    return 0;      }      if(null == (fstream = popen(command,"r")))            {               fprintf(stderr,"execute command failed: %s",strerror(errno));                return -1;            }            while(null != fgets(buff, sizeof(buff), fstream))      {            //printf("%s",buff);    if ( send(connfd, buff,strlen(buff), 0) < 0 ) //将命令执行结果发送至客户端              printf( "send failed" );          }/*  if(null != fgets(buff, sizeof(buff), fstream))      {            //printf("%s",buff);    if ( send(connfd, buff,strlen(buff), 0) < 0 )              printf( "send failed" );          }else{  if ( send(connfd, "..",sizeof("buff"), 0) < 0 )              printf( "send failed" );  }*/      pclose(fstream);             return 0;       }        int main( int argc, char *argv[] )  {      int    sockfd, connfd;      int optval;      int recv_type = username;  //默认为username,即用户名输入模式      int client_size;      int recv_bits;        char buffer[ buf_size ];         pid_t pid;      struct sockaddr_in client_addr, server_addr;         client_size = sizeof( struct sockaddr_in );      /* 初始化各变量为零 */      memset( buffer, 0, buf_size );      memset( &server_addr, 0, sizeof(server_addr) );      memset( &client_addr, 0, sizeof(server_addr) );         if ( (sockfd = socket(af_inet, sock_stream, 0)) < 0 )  //创建socket          printf( "socket failed" );         /* 设置端口快速重用*/      optval = 1;      if ( setsockopt(sockfd, sol_socket, so_reuseaddr, (void *)&optval, sizeof(int)) < 0 )          printf( "setsockopt failed" );         server_addr.sin_family = af_inet;      server_addr.sin_port = htons( port );      server_addr.sin_addr.s_addr = htonl( inaddr_any );        if ( bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0 ) //绑定ip和端口号          printf( "bind failed" );         if ( listen(sockfd, max_listen) < 0 ) //建立监听          printf( "listen failed" );     printf("telnet服务器已开启……n");      while ( 1 ) {      if ( (connfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_size)) < 0 ) //响应客户端请求              printf( "accept failed" );          printf( "server accept a client: ip = %sn",inet_ntoa(client_addr.sin_addr) ); //打印客户端ip                    /* 创建子进程处理客户端请求 */          if ( (pid = fork()) == 0 ) {              while ( 1 ) {                  /* 接受客户端信息 */                  if ( (recv_bits = recv(connfd, buffer, buf_size, 0)) < 0 )                      printf( "recv failed" );                     /* 去除最后一个字符 */                  buffer[recv_bits - 1] = '';                     /* 用户名鉴定 */                  if ( recv_type == username ) {                      if ( strcmp(name, buffer) != 0 ) {                       if ( send(connfd, error_user,strlen(error_user), 0) < 0 )                              printf( "send failed" );  break;                      }else{  if ( send(connfd, correct_user,strlen(correct_user), 0) < 0 )                              printf( "send failed" );  }  printf("%s正在登录:",buffer);                          recv_type = password;  //设置标志为密码鉴定模式                  }                  /* 密码鉴定 */                  else if ( recv_type == password ) {                      if ( strcmp(passwd, buffer) != 0 ) { //验证密码                       if ( send(connfd, error_password,strlen(error_password), 0) < 0 )                              printf( "send failed" );                      } else {                         if ( send(connfd, success_login, strlen(success_login), 0) < 0 )                              printf( "send failed" );  printf("用户登录成功!n");  recv_type = command;  //设置标志为命令模式                      }                                  }  /* 命令模式 */  else if( recv_type == command ) {  command(connfd,buffer);     puts("客户端输入的命令为:");  puts(buffer);                                   }              }              close( sockfd );              close( connfd );              exit ( 0 );          }          else              close( connfd );      }      return 0;  }   

 

7.2客户端

#include <unistd.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <assert.h>  #include <errno.h>  #include <sys/types.h>  #include <sys/socket.h>  #include <arpa/inet.h>  #include <netinet/in.h>        #define true        1  #define false       -1  #define buf_size     1024     //登录过程状态标识  char *error_user = "error user name";  char *error_password = "error password";  char *correct_user = "correct user";  char *success_login = "correct password";  char *exit_command = "exit";  char *exit_tip="退出连接!";     /*  * 介绍:客户端  * 功能:  *    1.登录服务器端  *    2.登录后在服务器端对文件进行操作  */        int send_recv( int connfd,char flag )  {   /*       *  作用:客户端与服务器端信息的处理       *  connfd: 服务器端标识   *  flag: 输入类比标识      */      char input_buf[ buf_size ]; //定义字符串存放输入信息      char recv_buf[ buf_size ]; //定义字符串存放服务器端返回信息  memset(input_buf, 0, sizeof(input_buf));  memset(recv_buf, 0, sizeof(recv_buf));        fgets( input_buf, buf_size, stdin ); //获取用户输入      input_buf[strlen(input_buf) - 1] = ''; //去除最后一个输入的确认         /* 向服务器发送消息 */      if ( send(connfd, input_buf, buf_size, 0) < 0 )          printf( "send failed" );         /* 从服务器接受消息 */      if ( recv(connfd, recv_buf, buf_size, 0) < 0 )          printf( "recv failed" );     /* 用户名处理 */      if ( flag == 'u' ) {          if ( strcmp(recv_buf, error_user) == 0 ) {  //用户名错误              puts( error_user );              return false;          }      }  /* 密码处理 */      else if ( flag == 'p' ) {          if ( strcmp(recv_buf, error_password) == 0 )            {  puts( error_password );  //密码错误   return false;  }      }  /* 命令处理 */  else if( flag == 'c' )  {  if ( strcmp(recv_buf, exit_command) == 0 ) {  //退出  printf("连接已断开n");            return false;          }  puts(recv_buf); //命令结果输出  }      return true;  }        int main( int argc, char *argv[] )  {      int    connfd;      int serv_port;      char recv_buf[ buf_size ];      struct sockaddr_in    serv_addr;         if ( argc != 3 ) {          printf( "输入格式为: ./c  [ip] [port]n" );          exit ( 1 );      }         memset( &serv_addr, 0, sizeof(struct sockaddr_in) );//置零         serv_addr.sin_family = af_inet;      serv_addr.sin_port = htons( atoi(argv[2]) );      inet_aton( argv[1], &serv_addr.sin_addr );         if ( serv_addr.sin_port == 0 ||serv_addr.sin_addr.s_addr == 0 ) {          fprintf( stderr, "输入格式为: ./c  [ip] [port]n" );          exit ( 1 );      }         connfd = socket( af_inet, sock_stream, 0 );  //创建socket      if ( connfd < 0 )          printf( "socket failed" );         if ( connect(connfd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) < 0 ) //连接服务器      {              printf( "connect failed" );      exit(0);      }  printf("请输入用户名:");  /*输入操作*/      if ( send_recv( connfd, 'u' ) == true )  {     printf("请输入密码:");         if ( send_recv( connfd,'p' )== true )  {  while(1)  {  printf("guest@ubantu:");  if ( send_recv( connfd, 'c' )== false )  {      close( connfd );          exit(0);  }  }  }  }      close( connfd );      return 0;  }   

 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/605411.html

(0)
上一篇 2021年5月13日
下一篇 2021年5月13日

精彩推荐