基于TCP协议简易聊天室(客户端)

来源:互联网 发布:数据挖掘算法入门案例 编辑:程序博客网 时间:2024/04/27 19:42

客户端:


/*********************************************************

-  File name    :chat.c

*  ******************************************************/

 

#include "../../include/net.h"

 

int sayto_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    

    /* 私聊验证 */

    newnode->ack = sayto;

 

    printf("你想发给谁\n");

    scanf("%s",newnode->toname);

 

    /* 异常处理 */

    if(getchar() != '\n')

    {

        printf("用户名格式不正确\n");

printf("\n请重新输入指令\n");

while(getchar() != '\n')

{

    continue;

}

return 0;

    }

 

 

    printf("你想对他说什么\n");

    gets(newnode->msg);

 

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

int sayall_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    

    /* 群聊验证 */

    newnode->ack = sayall;

 

    printf("你想对他们说什么\n");

    gets(newnode->msg);

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

int dis_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    newnode->ack = dis;

 

    write(sfd, newnode, sizeof(Node));

 

    printf("你当前在线好友为\n");

 

    return 0;

}

 

int change_1(int sfd)

{

    int i;

    char buf[10];

    char buf_1[10];

    char buf_2[10];

 

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    newnode->ack = change;

 

    memset(buf, 0, sizeof(buf));

    memset(buf_1, 0, sizeof(buf_1));

    memset(buf_2, 0, sizeof(buf_2));

 

    printf("请输入你的原先密码\n");

    printf("请输入修改后的密码\n");

    printf("    密码确认\n");

    printf("\033[3A");

    

    printf("\t\t\t\t");

    for(i = 0; (buf[i++] = my_getch()) != '\n'; )

    {

        printf("*");

    }

    buf[i - 1] = '\0';

 

    strcpy(newnode->password, buf);

 

    while(1)

    {

        printf("\t\t\t\t");

        memset(buf_1, 0, sizeof(buf_1));

        for(i = 0; (buf_1[i++] = my_getch()) != '\n'; )

{

            printf("*");

        }

 

        printf("\t\t\t\t");

        memset(buf_2, 0, sizeof(buf_2));

        for(i = 0; (buf_2[i++] = my_getch()) != '\n'; )

        {

    printf("*");

        }

 

        if(strcmp(buf_1,buf_2) == 0)

{

            break;

}

        else

{

            printf("两次密码输入不相同\n");

    printf("请重新输入\n");

}

    }

    buf_1[i - 1] = '\0';

    strcpy(newnode->msg, buf_1);

    printf("newnode = %s\n", newnode->msg);

 

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

/*********************************************************

-  File name    :history_recv.c

*  ******************************************************/

 

#include "../../include/net.h"

 

int history_recv(Node *newnode, int flag)

{

    char buf[100];

    char history_msg[1024];

 

    char *sql;

    char *errmsg;

    

    time_t time_now;

 

    memset(buf, 0, sizeof(buf));

    sprintf(buf, "create table if not exists %s(history varchar(1024));", newnode->toname);

    sql = buf;

 

    if(SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, &errmsg))

    {

        perror("sqlite3_exec create error!\n");

exit(0);

    }

 

    memset(history_msg, 0, sizeof(history_msg));

    if(flag == MSG_RECV_ONE)

    {

        time(&time_now);

        sprintf(history_msg, "%s%-6s对你说:%s", ctime(&time_now), newnode->name, newnode->msg);

        memset(buf, 0, sizeof(buf));

sprintf(buf, "insert into %s values('%s');", newnode->toname, history_msg);

        sql = buf;

printf("%s\n", sql);

 

if(SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, &errmsg))

{

    perror("sqlite3_exec insert error!\n");

    exit(0);

}

    }

 

    return 0;

}

/*********************************************************

-  File name    :my_getch.c

*  ******************************************************/

 

#include <stdio.h>

#include <termios.h>

 

#include "../../include/net.h"

 

char my_getch()

{

    struct termios stored_settings;

    struct termios new_settings;

 

    tcgetattr (0,&stored_settings);

 

    new_settings = stored_settings;

    new_settings.c_lflag &= (~ICANON);

    new_settings.c_cc[VTIME] = 0;

    new_settings.c_cc[VMIN] = 1;

 

    tcsetattr(0,TCSANOW,&new_settings);

 

    char ch;

 

    ch = getchar();

    putchar('\b');                           //删除回显

 

    tcsetattr(0,TCSANOW,&stored_settings);   //恢复系统设置

 

    return ch;

}

 

char get_choice()

{

    char src[10];

    

    while (1)

    {   

        gets(src);

 

if (strcmp("reg",src) == 0)

{

    return reg;

}

else if (strcmp("log",src) == 0)

{

    return log;

}

else if (strcmp("sayto",src) == 0)

{

    return sayto;

}

else if (strcmp("sayall",src) == 0)

{

    return sayall;

}

else if (strcmp("dis",src) == 0)

{

    return dis;

}

else if (strcmp("change",src) == 0)

{

    return change;

}

else if(strcmp("send_file", src) == 0)

{

    return send_file;

}

else if (strcmp("stop_say",src) == 0)

{

    return stop_say;

}

else if (strcmp("let_say",src) == 0)

{

    return let_say;

}

else if (strcmp("t_man",src) == 0)

{

    return t_man;

}

else if (strcmp("quit",src) == 0)

{

    return quit;

}

else

{

    printf("\n请输入正确指令\n");

}

    }    

}

/*********************************************************

-  File name    :net.h

*  ******************************************************/

 

#ifndef _NET_H_

#define _NET_H_

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <fcntl.h>

#include <unistd.h>

#include <signal.h>

#include <pthread.h>

#include <termios.h>

#include <sqlite3.h>

 

struct node

{

    int ack;

    char id[9];

    char name[20];

    char password[10];

    char toname[20];

    char msg[1024];

    char file_name[100];

    char file_msg[1024];

};

 

typedef struct node Node;

 

struct online

{

    int sfd;

    int on_flag;

    int speek_flag;

    char name[20];

 

    struct online *next;

};

 

typedef struct online Online;

 

enum

{

    reg = 0,         // 注册

    log,             // 登录

    sayto,           // 私聊

    sayall,          // 群聊

    dis,             // 查看在线用户

    change,          // 修改密码

    send_file,       // 发送文件

    stop_say,        // 禁言

    let_say,         // 解禁

    t_man,           // 踢人

    quit = 10,            // 退出

    SUCCESS,         // 成功

    FAILE,           // 失败

    sup,             // 超级用户

    EXIT,            // 用户存在

    NOT_EXIT,        // 用户不存在

    PASSWD_ERR,      // 密码错误

    SUCCESS_LOG,     // 成功登录

    REG_NOT_EXIT,    // 注册名可用

    REG_EXIT,        // 注册名不可用

    SUCCESS_REG = 20,     // 成功注册

    No_say,          // 已经被禁言

    Ok_say,          // 你已被解禁

    MSG_RECV_ONE,    // 接收私聊

    MSG_RECV_ALL,    // 接收群聊

    DIS_NAME,        // 列出当前在线用户

    PASSWD_SUCCESS,  // 修改密码成功

    RECV_FILE,       // 接受文件

    STOP_SAY_OK,     // 禁言成功

    NOT_STOP_SAY,    // 并没有被禁言

    LET_SAY_OK = 30,      // 解禁成功

    No_online,       // 无其他用户在线

    T_OK,            // 踢人成功

    YOU_OUT,         // 提示用户被踢

    QUIT_OK,         // 成功退出

    chat             // 聊天界面

};

 

extern sqlite3 *db;

 

void read_msg(void *arg);

 

void passwd(void *arg);

 

char get_choice();

 

extern int Flag;

 

int change_1(int sfd);

 

int chat_one(int sfd);

 

int dis_1(int sfd);

 

char my_getch();

 

char get_choice();

 

int let_say_1(int sfd);

 

int log_1(int sfd);

 

void menu_start();

 

void menu_chat();

 

void menu_sup();

 

int reg_1(int sfd);

 

int sayto_1(int sfd);

 

int sayall_1(int sfd);

 

int send_1(int sfd);

 

int recv_file(Node *newnode);

 

int stop_say_1(int sfd);

 

int t_man_1(int sfd);

 

int tcp_connect(const char *ip);

 

int history_recv(Node *newnode, int flag);

 

#endif

 

/*********************************************************

-  File name    :log_reg.c

*  ******************************************************/

 

#include "../../include/net.h"

 

int log_1(int sfd)

{

    int i;

 

    char buf[10];

    char temp[20];

 

    Node *newnode = (Node *) malloc (sizeof(Node));

 

    memset(newnode, 0, sizeof(Node));

    newnode->ack = log;

 

    system("clear");

    printf("+-----------------------------------+\n");

    printf("|                                   |\n");

    printf("|             登录帐号              |\n");

    printf("|                                   |\n");

    printf("+-----------------------------------+\n");

    printf("|                                   |\n");

    printf("|                                   |\n");

    printf("|   帐    号:                       |\n");

    printf("|                                   |\n");

    printf("|                                   |\n");

    printf("|   密    码:                       |\n");

    printf("|                                   |\n");

    printf("|                                   |\n");

    printf("+-----------------------------------+\n");

 

    printf("\033[8;16H ");

    gets(newnode->id);

 

    memset(temp, 0 ,sizeof(temp));

    strcpy(temp, newnode->id);

 

    for(i = 0; i < 20; i++)

    {

        if(temp[i] == ' ')

{

            printf("\033[16;10H ");

            printf("用户名不合法,请重新输入\n");

            printf("\033[18;10H ");

    printf("    请按ENTER键返回\n");

 

    while(getchar() != '\n')

    {

        continue;

    }

    return 0;

}

    }

    

    printf("\033[11;16H ");

    memset(buf, 0, sizeof(buf));

    for(i = 0; (buf[i++] = my_getch()) != '\n'; )

    {

        printf("*");

    }

    buf[i - 1] = '\0';

 

    strcpy(newnode->password,buf);

 

    /* 发送帐户信息 */

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

int reg_1(int sfd)

{

    int i;

   

    char temp[20];

    char buf_1[10] = {0};

    char buf_2[10] = {0};

 

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    

    newnode->ack = reg;

 

    system("clear");

    printf("+-----------------------------------+\n");

    printf("|                                   |\n");

    printf("|             注册帐号              |\n");

    printf("|                                   |\n");

    printf("+-----------------------------------+\n");

    printf("|                                   |\n");

    printf("|   帐    号:                       |\n");

    printf("|                                   |\n");

    printf("|   密    码:                       |\n");

    printf("|                                   |\n");

    printf("|   密码确认:                       |\n");

    printf("|                                   |\n");

    printf("+-----------------------------------+\n");

    printf("\033[7;16H ");

 

    gets(newnode->name);

 

    memset(temp, 0 ,sizeof(temp));

    strcpy(temp, newnode->name);

 

    for(i = 0; i < 20; i++)

    {

        if(temp[i] == ' ')

{

            printf("\033[16;10H ");

            printf("用户名不合法,请重新输入\n");

            printf("\033[18;10H ");

    printf("    请按ENTER键返回\n");

 

    while(getchar() != '\n')

    {

        continue;

    }

    return 0;

}

    }

    

    while(1)

    {

        printf("\033[9;16H ");

        memset(buf_1, 0, sizeof(buf_1));

        for(i = 0; (buf_1[i++] = my_getch()) != '\n'; )

{

            printf("*");

        }

 

        printf("\033[11;16H ");

        memset(buf_2, 0, sizeof(buf_2));

        for(i = 0; (buf_2[i++] = my_getch()) != '\n'; )

        {

    printf("*");

        }

 

        if(strcmp(buf_1,buf_2) == 0)

{

            break;

}

        else

{

            printf("两次密码输入不相同\n");

    printf("请重新输入\n");

}

    }

    buf_1[i - 1] = '\0';

    strcpy(newnode->password,buf_1);

    

    /* 发送帐户信息 */

    write(sfd, newnode, sizeof(Node));

    

    return 0;

 

}

 

/*********************************************************

-  File name    :main.c

*  ******************************************************/

 

#include "../../include/net.h"

 

sqlite3 *db = NULL;

 

pthread_mutex_t mutex;

 

int Flag = reg;

 

int main(int argc, char **argv)

{

    if(argc != 2)

    {

        printf("Usage: <IP Address>\n");

exit(-1);

    }

 

    int rc;

 

    if(SQLITE_OK != (rc = sqlite3_open("history.db", &db)))

    {

        perror("sqlite3_open error!\n");

exit(0);

    }

    

    int sfd = tcp_connect(argv[1]);

 

    char ch = '0';

 

    pthread_t id;

 

    pthread_create(&id, NULL, (void *)read_msg, (void *)&sfd);

 

    while(Flag == reg)

    {

        system("clear");

        menu_start();

 

        if((ch = get_choice()) != quit)

{

            switch(ch)

    {

        case log:

        {

            log_1(sfd);

    sleep(1);

            break;

        }

 

        case reg:

        {

            reg_1(sfd);

            break;

        }

 

        default:

        {

            printf("start error!\n");

            exit(0);

        }

    }

        }

    }

 

    if(Flag == chat)

    {

        system("clear");

        menu_chat();

        while((ch = get_choice()) != quit)

        {

    if(Flag == YOU_OUT)

    {

        printf("请重新登录\n");

        break;

    }

 

    switch(ch)

    {

        case sayto:

                {

           sayto_1(sfd);

           break;

        }

 

        case sayall:

                {

    sayall_1(sfd);

                    break;

        }

 

        case dis:

                {

                    dis_1(sfd);

    break;

        }

 

        case change:

        {

                    change_1(sfd);

    break;

        }

 

case send_file:

{

    send_1(sfd);

    break;

}

        default:

        {

                    printf("chat error!\n");

    exit(0);

        }

    }

        }

    }

    else if(Flag == sup)

    {

        system("clear");

menu_sup();

while((ch = get_choice()) != quit)

{

    switch(ch)

    {

        case stop_say:

{

    stop_say_1(sfd);

    break;

}

 

case let_say:

{

    let_say_1(sfd);

    break;

}

        case t_man:

        {

            t_man_1(sfd);

    break;

        }

 

default:

{

    printf("sup error!\n");

    exit(0);

}

    }

}

    }

 

    if(ch == quit)

    {

        Node *newnode = (Node *) malloc (sizeof(Node));

memset(newnode, 0, sizeof(Node));

newnode->ack = quit;

write(sfd, newnode, sizeof(Node));

sleep(1);

    }

 

    return 0;

}

 

/*********************************************************

-  File name    :menu.c

*  ******************************************************/

 

#include "../../include/net.h"

 

void menu_start()

{

    printf("+-----------------------------------+\n");

    printf("|                                   |\n");

    printf("|             欢迎使用              |\n");

    printf("|                           V1.0    |\n");

    printf("+-----------------------------------+\n");

    printf("|                                   |\n");

    printf("|                                   |\n");

    printf("|   登录(log)           注册(reg)   |\n");

    printf("|                                   |\n");

    printf("|                                   |\n");

    printf("+-----------------------------------+\n");

}

 

void menu_chat()

{

    printf("+-------------------------------------+\n");

    printf("|                                     |\n");

    printf("|             欢迎使用                |\n");

    printf("|                           V1.0      |\n");

    printf("+-------------------------------------+\n");

    printf("|                                     |\n");

    printf("|      你想和谁说悄悄话  (sayto)      |\n");

    printf("|      你想和大家说些什么(sayall)     |\n");

    printf("|      看看当前在线好友  (dis)        |\n");

    printf("|      修改密码          (change)     |\n");

    printf("|      离开吗            (quit)       |\n");

    printf("|                                     |\n");

    printf("+-------------------------------------+\n");

}

 

void menu_sup()

{

    printf("+-------------------------------------+\n");

    printf("|                                     |\n");

    printf("|            你是超级用户             |\n");

    printf("|                                     |\n");

    printf("+-------------------------------------+\n");

    printf("|                                     |\n");

    printf("|         你想禁言谁    (stop_say)    |\n");

    printf("|         你想解禁谁    (let_say)     |\n");

    printf("|         你又想将谁踢掉(t_man)       |\n");

    printf("|         离开吗        (quit)        |\n");

    printf("|                                     |\n");

    printf("+-------------------------------------+\n");

}

 

/*********************************************************

-  File name    :read_msg.c

*  ******************************************************/

 

#include "../../include/net.h"

 

void read_msg(void *arg)

{

    int sfd = *((int *)arg);

    int nread;

    

    Node *newnode = (Node *) malloc (sizeof(Node));

    

    while(1)

    {

        memset(newnode, 0, sizeof(Node));

 

if((nread = read(sfd, newnode, sizeof(Node))) == 0)

        {

    close(sfd);

    pthread_exit(NULL);

}

switch(newnode->ack)

{

    case sup:    //admin

    {

        printf("登录成功!\n");

Flag = sup;

        break;

    }

 

    case EXIT:

    {

        printf("用户已登录,请不要重复登录\n");

        break;

    }

 

    case NOT_EXIT:

    {

        printf("您输入的用户名不存在!\n");

printf("请重新输入!\n");

        break;

    }

 

    case PASSWD_ERR:

    {

        printf("密码不正确,请重新输入\n");

Flag = reg;

        break;

    }

 

    case SUCCESS_LOG:

    {

        printf("登录成功!\n");

Flag = chat;

break;

    }

            /******************

    case REG_NOT_EXIT:

    {

menu_start();

        break;

    }

    ******************/

 

    case REG_EXIT:

    {

printf("用户已存在,请重新输入\n");

Flag = reg;

break;

    }

    case SUCCESS_REG:

    {

        printf("注册成功\n");

printf("请记住你的ID:  %s\n",newnode->id);

Flag = reg;

break;

    }

 

    case MSG_RECV_ONE:

    {

        printf("%s 悄悄对你说 %s\n",newnode->name,newnode->msg);

history_recv(newnode, MSG_RECV_ONE);

break;

    }

 

    case MSG_RECV_ALL:

    {

        printf("%s 对大家说 %s\n",newnode->name, newnode->msg);

history_recv(newnode, MSG_RECV_ALL);

break;

    }

 

    case DIS_NAME:

    {

printf("%s\n",newnode->name);

break;

    }

 

    case RECV_FILE:

    {

        printf("%s 向你发送了%s文件\n", newnode->name, newnode->file_name);

recv_file(newnode);

 

printf("接受成功\n");

break;

    }

 

    case PASSWD_SUCCESS:

    {

        printf("密码修改成功\n");

break;

    }

 

    case STOP_SAY_OK:

    {

        printf("禁言成功\n");

break;

    }

 

    case No_say:

    {

        printf("你已经被禁言\n");

break;

    }

 

    case NOT_STOP_SAY:

    {

        printf("该用户没有被禁言\n");

break;

    }

 

    case LET_SAY_OK:

    {

        printf("解禁成功\n");

break;

    }

 

    case Ok_say:

    {

        printf("你已被解禁\n");

break;

    }

 

    case No_online:

    {

        printf("当前没有其他用户在线\n");

break;

    }

 

    case T_OK:

    {

        printf("踢人成功\n");

break;

    }

    

    case YOU_OUT:

    {

        printf("你已被踢下线\n");

Flag = YOU_OUT;

break;

    }

 

    case QUIT_OK:

    {

        printf("期待你的回归\n");

break;

    }

 

    default:

    {

        printf("read_msg error!\n");

exit(0);

    }

}

    }

}

 

Scripts:

 

CC := gcc

CFLAGS := -Wall -O3

Libs = -lpthread -lsqlite3

Target := client

Source := $(wildcard src/*.c)

Objs := $(patsubst %.c,%.o,$(Source))

Modules += chat get log_reg main menu read_msg send_recv_file sup tcp_socket

AllObjs := $(addsuffix /src/*.o,$(Modules))

 

/*********************************************************

-  File name    :send_recv.c

*  ******************************************************/

 

#include "../../include/net.h"

 

int send_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

 

    /* 发送文件验证 */

    newnode->ack = send_file;

 

    printf("你想对谁发送文件:\n");

    scanf("%s",newnode->toname);

 

    /* 异常处理 */

    if(getchar() != '\n')

    {

        printf("用户名格式不正确\n");

printf("\n请重新输入指令\n");

while(getchar() != '\n')

{

    continue;

}

return 0;

    }

 

    printf("请输入要传输文件的文件名:\n");

    scanf("%s", newnode->file_name);

    getchar();

 

    int fd = open(newnode->file_name, O_RDONLY);

    int file_len = lseek(fd, 0, SEEK_END);

 

    int read_len = 0;

    int n = 0;

    /* 将文件写入结构体 */

    lseek(fd, 0, SEEK_SET);

    while(read_len < file_len)

    {

        n = read(fd, newnode->file_msg + read_len, file_len - read_len);

 

if(n < 0)

{

    perror("write file error!\n");

    return 0;

}

 

read_len += n;

    }

    

    /* 发送给服务器 */

 

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

int recv_file(Node *newnode)

{

    int fd;

    int recv_len = strlen(newnode->file_msg);

    int write_len = 0;

    int n = 0;

 

    if((fd = open("abcd", O_RDWR | O_CREAT | O_TRUNC, 0755)) < 0)

    {

        perror("open error!\n");

exit(0);

    }

 

    while(write_len < recv_len)

    {

        n = write(fd, newnode->file_msg + write_len , recv_len - write_len);

if(n < 0)

{

    perror("read file error");

    exit(0);

}

 

write_len += n;

    }

 

    return 0;

}

 

/*********************************************************

-  File name    :sup.c

*  ******************************************************/

 

#include "../../include/net.h"

 

int stop_say_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

 

    newnode->ack = stop_say;

 

    printf("请输入你将谁禁言\n");

    scanf("%s",newnode->name);

    getchar();

 

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

int let_say_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    newnode->ack = let_say;

 

    printf("请输入你要解禁的用户名\n");

    scanf("%s",newnode->name);

    getchar();

 

    write(sfd, newnode, sizeof(Node));

 

    return 0;

}

 

int t_man_1(int sfd)

{

    Node *newnode = (Node *) malloc (sizeof(Node));

    memset(newnode, 0, sizeof(Node));

    newnode->ack = t_man;

    

    printf("你想踢谁\n");

    scanf("%s",newnode->name);

    write(sfd, newnode, sizeof(Node));

 

    getchar();

 

    return 0;

}

 

/*********************************************************

-  File name    :tcp_socket.c

*  ******************************************************/

 

#include "../../include/net.h"

 

int tcp_connect(const char *ip)

{

    int sfd;

    if((sfd = socket(AF_INET, SOCK_STREAM,0)) == -1)

    {

        perror("socket error!\n");

exit(-1);

    }

 

    struct sockaddr_in severaddr;

    bzero(&severaddr,sizeof(severaddr));

    severaddr.sin_family = AF_INET;

    severaddr.sin_addr.s_addr = inet_addr(ip);

    severaddr.sin_port = htons(8888);

 

    if(connect(sfd, (struct sockaddr *)&severaddr, sizeof(severaddr)) == -1)

    {

        perror("connect error!\n");

close(sfd);

exit(-1);

    }

 

    return sfd;

}

 

 

 

 


原创粉丝点击