Chinaunix首页 | 论坛 | 博客
  • 博客访问: 34275
  • 博文数量: 8
  • 博客积分: 1482
  • 博客等级: 上尉
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-18 13:55
文章分类

全部博文(8)

文章存档

2011年(1)

2008年(7)

我的朋友

分类: C/C++

2008-10-31 11:28:39

     随手写了个模拟telnet登录的程序,包括服务器和测试客户端,主要思想其实是很简单,就是:服务器保存了一些users和相关的password,客户端想登录就输入用户名,然后客户端把用户名发送到服务器上,服务器检查是否存在该用户,存在就提示用户输入密码,不存在,就输出错误信息,接下来就是同样道理,检查密码了。
代码很短,因为本来就简单,接下来可能会完善这个程序,让它模拟telnet服务器的操作,而不是单单登录而已。



#ifndef TELNET_H
#define TELNET_H

#define PORT         8003

#define MAX_LISTEN    10
#define BUF_SIZE     1024
#define MAX_LEN        125

#define TRUE        1
#define FALSE        -1

#define USERNAME    0
#define PASSWORD    1    

struct user_info {
    char username[ MAX_LEN ];
    char password[ MAX_LEN ];
};

struct user_info users[] = {
    { "ken", "ken" },
    { "linux", "123" },
    { "admin", "123" },
    { " ", " " },
};

char *error_user = "error user name";
char *error_password = "error password";
char *correct_user = "correct user";
char *success_login = "login, welcome";

#endif

/*
 * filename: telnet_client.c
 * DESC:      Imitate the telnet login the sever point.
 * Author: linjian
 * E-mail: lin.jian1986@gmail.com
 * Date: 2008/10/27
 * VERSION: 1.0
 */


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

#include "../my_error.h"
#include "telnet.h"

/*
 * @connfd: the file desc of the connection
 * @string: the message string
 * DESC:    input the login name and password
 */

int input_client_info( int connfd, const char *string, char flag )
{
    char input_buf[ BUF_SIZE ];
    char recv_buf[ BUF_SIZE ];

    printf( "%s: ", string );
    fgets( input_buf, BUF_SIZE, stdin );
    input_buf[strlen(input_buf) - 1] = '\0';

    /* send the result to the sever point */
    if ( send(connfd, input_buf, BUF_SIZE, 0) < 0 )
        my_error( "send failed" );

    /* recv the message from the sever */
    if ( recv(connfd, recv_buf, BUF_SIZE, 0) < 0 )
        my_error( "recv failed" );

    if ( flag == 'u' ) {
        /* whether the user name is error */
        if ( strcmp(recv_buf, error_user) == 0 ) {
            puts( error_user );
            return FALSE;
        }
    }
    else if ( flag == 'p' ) {
        /* whether the password is error */
        if ( strcmp(recv_buf, error_password) == 0 )
            puts( error_password );
        else
            puts( success_login );
    }
    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( "usage: ./telnet_client [port] [ip]\n" );
        exit ( 1 );
    }

    memset( &serv_addr, 0, sizeof(struct sockaddr_in) );
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons( atoi(argv[1]) );
    inet_aton( argv[2], &serv_addr.sin_addr );

    if ( serv_addr.sin_port == 0 ||

         serv_addr.sin_addr.s_addr == 0 ) {
        fprintf( stderr, "usage: ./telnet_client [port] [ip]\n" );
        exit ( 1 );
    }

    connfd = socket( AF_INET, SOCK_STREAM, 0 );
    if ( connfd < 0 )
        my_error( "socket failed" );

    if ( connect(connfd, (struct sockaddr *)&serv_addr,

         sizeof(struct sockaddr)) < 0 )
        my_error( "connect failed" );

    if ( input_client_info( connfd, "username", 'u' ) == TRUE )
        input_client_info( connfd, "password", 'p' );

    close( connfd );
    return 0;
}

/*
 * filename: telnet_server.c
 * DESC:      Imitate the telnet login the sever point.
 * Author: linjian
 * E-mail: lin.jian1986@gmail.com
 * Date: 2008/10/27
 * VERSION: 1.0
 */


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

#include "../my_error.h"
#include "telnet.h"

/*
 * @name: the user name from client point
 * DESC: to find the name in the server point
 */

int find_user_name( const char *name )
{
    assert( name != NULL );

    for ( int i = 0; users[i].username[0] != ' '; ++i )
        if ( strcmp(users[i].username, name) == 0 )
            return i;

    return FALSE;
}

int main( int argc, char *argv[] )
{
    int    sockfd, connfd;
    int optval;
    int recv_type = USERNAME;
    int client_size;
    int recv_bits;
    int name_index;
    char buffer[ BUF_SIZE ];

    pid_t pid;
    struct sockaddr_in client_addr, server_addr;

    /* initialize some variables */
    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 )
        my_error( "socket failed" );

    /* set the option and the sockfd can rebind points */
    optval = 1;
    if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
                 (void *)&optval, sizeof(int)) < 0 )
        my_error( "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 )
        my_error( "bind failed" );

    if ( listen(sockfd, MAX_LISTEN) < 0 )
        my_error( "listen failed" );

    while ( 1 ) {
        if ( (connfd = accept(sockfd,

             (struct sockaddr*)&client_addr, &client_size)) < 0 )
            my_error( "accept failed" );

        printf( "Server accept a client: ip = %s\n",

                 inet_ntoa(client_addr.sin_addr) );
        
        /* the child process is used to deal with the connection */
        if ( (pid = fork()) == 0 ) {
            while ( 1 ) {
                /* recieve the string from the client point */
                if ( (recv_bits =

                      recv(connfd, buffer, BUF_SIZE, 0)) < 0 )
                    my_error( "recv failed" );

                /* delete the last character of the buffer string */
                buffer[recv_bits - 1] = '\0';
                puts(buffer);

                /* the buffer is user's name */
                if ( recv_type == USERNAME ) {
                    name_index = find_user_name( buffer );
                    if ( name_index == FALSE ) {
                        if ( send(connfd, error_user, 

                             strlen(error_user), 0) < 0 )
                            my_error( "send failed" );
                        break;
                    } else {
                        if ( send(connfd, correct_user,

                             strlen(correct_user), 0) < 0 )
                            my_error( "send failed" );
                        recv_type = PASSWORD;
                    }
                }
                /* the buffer is user's password */
                else if ( recv_type == PASSWORD ) {
                    if ( strcmp(users[name_index].password, buffer)

                        != 0 ) {
                        if ( send(connfd, error_password,

                             strlen(error_password), 0) < 0 )
                            my_error( "send failed" );
                    } else {
                        if ( send(connfd, success_login,

                            strlen(success_login), 0) < 0 )
                            my_error( "send failed" );
                    }
                    break;
                }
            }
            close( sockfd );
            close( connfd );
            exit ( 0 );
        }
        else
            close( connfd );
    }

    return 0;
}

// 运行结果如下:

ken@ken-laptop:~/linux_c/chap11$ ./telnet_client 8003 127.0.0.1
username: ken
password: ken
login, welcome
ken@ken-laptop:~/linux_c/chap11$ ./telnet_client 8003 127.0.0.1
username: dsf
error user name
ken@ken-laptop:~/linux_c/chap11$ ./telnet_client 8003 127.0.0.1
username: admin
password: 123
login, welcome

阅读(1950) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~