Telnet模拟系统(Linux c)

服务器   发布日期:2025年08月14日   浏览次数:406

3.1相关技术

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

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

  3)对文件的读写操作

  4)popen调用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 = %s\n",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] = '\0';

 

                /* 用户名鉴定 */

                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] = '\0'; //去除最后一个输入的确认

 

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

    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="";
 
#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[];    
    memset(buff, , sizeof(buff));   
if ( strcmp(exit_command, command) ==  ) { //退出
        if ( send(connfd, exit_command,strlen(exit_command), ) <  )
          printf( "send failed" );
printf("客户端已断开连接!\n");
  return ;
    }
    if(NULL == (fstream = popen(command,"r")))      
    {     
        fprintf(stderr,"execute command failed: %s",strerror(errno));      
        return -;      
    }   
 
    while(NULL != fgets(buff, sizeof(buff), fstream))
    {  
        //printf("%s",buff);  
if ( send(connfd, buff,strlen(buff), ) <  ) //将命令执行结果发送至客户端
            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 ;     
}
 
 
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, , BUF_SIZE );
    memset( &server_addr, , sizeof(server_addr) );
    memset( &client_addr, , sizeof(server_addr) );
 
    if ( (sockfd = socket(AF_INET, SOCK_STREAM, )) <  )  //创建socket
        printf( "socket failed" );
 
    /* 设置端口快速重用*/
    optval = ;
    if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) <  )
        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)) <  ) //绑定ip和端口号
        printf( "bind failed" );
 
    if ( listen(sockfd, MAX_LISTEN) <  ) //建立监听
        printf( "listen failed" );
 
printf("telnet服务器已开启……\n");
    while (  ) {
    if ( (connfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_size)) <  ) //响应客户端请求
            printf( "accept failed" );
        printf( "Server accept a client: ip = %s\n",inet_ntoa(client_addr.sin_addr) ); //打印客户端ip
        
        /* 创建子进程处理客户端请求 */
        if ( (pid = fork()) ==  ) {
            while (  ) {
                /* 接受客户端信息 */
                if ( (recv_bits = recv(connfd, buffer, BUF_SIZE, )) <  )
                    printf( "recv failed" );
 
                /* 去除最后一个字符 */
                buffer[recv_bits - ] = '\0';
 
                /* 用户名鉴定 */
                if ( recv_type == USERNAME ) {
                    if ( strcmp(name, buffer) !=  ) {
                     if ( send(connfd, error_user,strlen(error_user), ) <  )
                            printf( "send failed" );
break;
                    }else{
if ( send(connfd, correct_user,strlen(correct_user), ) <  )
                            printf( "send failed" );
}
printf("%s正在登录:",buffer);
                        recv_type = PASSWORD;  //设置标志为密码鉴定模式
                }
                /* 密码鉴定 */
                else if ( recv_type == PASSWORD ) {
                    if ( strcmp(passwd, buffer) !=  ) { //验证密码
                     if ( send(connfd, error_password,strlen(error_password), ) <  )
                            printf( "send failed" );
                    } else {
                       if ( send(connfd, success_login, strlen(success_login), ) <  )
                            printf( "send failed" );
printf("用户登录成功!\n");
recv_type = COMMAND;  //设置标志为命令模式
                    }                
                }
/* 命令模式 */
else if( recv_type == COMMAND ) {
command(connfd,buffer);   
puts("客户端输入的命令为:");
puts(buffer);                 
                }
            }
            close( sockfd );
            close( connfd );
            exit (  );
        }
        else
            close( connfd );
    }
    return ;
}
 

 

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, , sizeof(input_buf));
memset(recv_buf, , sizeof(recv_buf));
    
fgets( input_buf, BUF_SIZE, stdin ); //获取用户输入
    input_buf[strlen(input_buf) - ] = '\0'; //去除最后一个输入的确认
 
    /* 向服务器发送消息 */
    if ( send(connfd, input_buf, BUF_SIZE, ) <  )
        printf( "send failed" );
 
    /* 从服务器接受消息 */
    if ( recv(connfd, recv_buf, BUF_SIZE, ) <  )
        printf( "recv failed" );
 
/* 用户名处理 */
    if ( flag == 'u' ) {
        if ( strcmp(recv_buf, error_user) ==  ) {  //用户名错误
            puts( error_user );
            return FALSE;
        }
    }
/* 密码处理 */
    else if ( flag == 'p' ) {
        if ( strcmp(recv_buf, error_password) ==  )
          {  puts( error_password );  //密码错误
 return FALSE;
}
    }
/* 命令处理 */
else if( flag == 'c' )
{
if ( strcmp(recv_buf, exit_command) ==  ) {  //退出
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 !=  ) {
        printf( "输入格式为: ./c  [ip] [port]\n" );
        exit (  );
    }
 
    memset( &serv_addr, , sizeof(struct sockaddr_in) );//置零
 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons( atoi(argv[]) );
    inet_aton( argv[], &serv_addr.sin_addr );
 
    if ( serv_addr.sin_port ==  ||serv_addr.sin_addr.s_addr ==  ) {
        fprintf( stderr, "输入格式为: ./c  [ip] [port]\n" );
        exit (  );
    }
 
    connfd = socket( AF_INET, SOCK_STREAM,  );  //创建socket
    if ( connfd <  )
        printf( "socket failed" );
 
    if ( connect(connfd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) <  ) //连接服务器
    {    
        printf( "connect failed" );
    exit();
    }
printf("请输入用户名:");
/*输入操作*/
    if ( send_recv( connfd, 'u' ) == TRUE )
{
   printf("请输入密码:");
       if ( send_recv( connfd,'p' )== TRUE )
{
while()
{
printf("guest@ubantu:");
if ( send_recv( connfd, 'c' )== FALSE )
{
    close( connfd );
        exit();
}
}
}
}
    close( connfd );
    return ;
}
 

 

以上就是Telnet模拟系统(Linux c)的详细内容,更多关于Telnet模拟系统(Linux c)的资料请关注九品源码其它相关文章!