小项目:即时通讯系统

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/dxd_123456/article/details/78369771

这个简单的通讯系统使用 C 语言完成编写,采用 C/S 架构,在 Linux 平台下,运用到 TCP/IP 协议,多线程编程的技术,使用几个简单 API 对 sqlite3 数据库进行操作,能实现注册,登录,群聊,私聊等几种功能。

下面是程序代码:
服务器端:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sqlite3.h> 
#include <stdlib.h>

#define PORT 9999

#define FALSE 0
#define TRUE  1



typedef struct Log_msg
{
    char name[20];
    int socket;
}log_msg;

typedef log_msg LinkData;

typedef struct _node
{
    LinkData data;
    struct _node *next;
}Node;

Node *head;

struct Msg
{
    int len;
    int a[20];
    char msg[1024];
    char name[20];
    char password[20];
    char guys[100];
    char toname[20];
    char fromname[20];
    char quitname[20];
    char logoutname[20];
    char sign[20];
    int cmd;
};



//创建链表
Node * Create_List()
{
    Node *list = (Node*)malloc(sizeof(Node)/sizeof(char));
    if (list == NULL)
        return NULL;

    list->next = NULL;   // 空表

    return list;
}




//尾插
int Insert_Last(Node *h, LinkData data)
{
    if (h == NULL)
        return FALSE;

    Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));
    if (node == NULL)
    {
        return FALSE;
    }
    node->data = data;
    node->next = NULL;

    Node* tmp = h;
    while (tmp->next)
    {
        tmp = tmp->next;
    }

    tmp->next = node;

    return TRUE;
}


int init_socket()
{
    //1.创建套接字socket
    int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
    if(listen_socket == -1)
    {
        perror("socket");
        return -1;
    }

    //2.命名套接字,绑定本地的IP地址和端口
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htons(INADDR_ANY);

    int ret = bind(listen_socket, (struct sockaddr *)&addr, sizeof(addr));
    if(ret == -1)
    {
        perror("bind");
        return -1;
    }

    //3.监听本地套接字
    ret = listen(listen_socket, 5);
    if(ret == -1)
    {
        perror("listen");
        return -1;
    }

    printf("等待客户端连接..........\n");
    return listen_socket;
}

//处理客户端连接,返回与连接上的客户端通信的套接字
int Accept(int listen_socket)
{
    //4.接收连接
    struct sockaddr_in client_addr;
    int len = sizeof(client_addr);
    int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
    if(client_socket == -1)
    {
        perror("accept");
        return -1;
    }

    printf("成功接收了一个客户端:%s\n", inet_ntoa(client_addr.sin_addr));

    return client_socket;

}

int reg(int client_socket, struct Msg *msg)//注册操作
{
    printf("%s进行注册\n", msg->name);

    //打开数据库chatroom
    sqlite3 *db;
    int ret = sqlite3_open("chatroom.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("打开数据库失败\n");
        return -1;
    }

    printf("打开数据库成功\n");

    //创建一张表login,用于存放用户的信息
    char *errmsg = NULL;
    char *sql = "create table if not exists login(name TEXT, password TEXT, sign TEXT, primary key(name))";
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    char buf[100];
    //将从客户端收来的信息存放到数据库中
    sprintf(buf, "insert into login values('%s', '%s', '%s')", msg->name, msg->password, msg->sign);
    ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败:%s\n", errmsg);
        msg->cmd = -1;
        return -1;
    }
    else
    {
        printf("插入信息成功\n");
        msg->cmd = 1001;
    }
    //反馈结果给客户端
    write (client_socket, msg, sizeof(struct Msg));

    sqlite3_close(db);

    return 0;

}

int login(int client_socket, struct Msg *msg)//登录操作
{
    printf("%s正在进行登录\n", msg->name);

    //打开数据库chatroom
    sqlite3 *db;
    int ret = sqlite3_open("chatroom.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("打开数据库失败\n");
        return -1;
    }

    printf("打开数据库成功\n");

    char *errmsg = NULL;

    char **resultp, **resultl;
    int nrow, ncolumn, lrow, lcolumn;
    char buf[100];
    char ptr[100];
    sprintf(buf, "select password from login where name = '%s'", msg->name);

    //在数据库中找出与传过来name对应的password
    ret = sqlite3_get_table(db, buf, &resultp, &nrow, &ncolumn, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败:%s\n", errmsg);
        return -1;
        msg->cmd = -1;
    }

    sprintf(ptr, "select * from login where name = '%s'", msg->name);
//  char *sql = "select name from login";
    //在数据库中找出与传过来name对应的password
    ret = sqlite3_get_table(db, ptr, &resultl, &lrow, &lcolumn, &errmsg);
    if(lrow == 0)
    {
        printf("不存在\n");
    //  return -1;
        msg->cmd = -2;
        write (client_socket, msg, sizeof(struct Msg));
        return -1;
        printf("不存在\n");
    }
//  int i;
//  char *t;


//  head = Create_List();
    Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));

    if(strcmp(resultp[1], msg->password) != 0)
    {
    //  printf("验证失败\n");
        msg->cmd = -1;
        printf("%d\n", msg->cmd);
        printf("验证失败\n");

    }
    else
    {
        printf("验证成功\n");
        msg->cmd = 1002;

        //登录成功后将登陆成功者的姓名和套接字存到链表head中
    //  printf("%s\n", msg->name);
        node->data.socket = client_socket;
        strcpy(node->data.name, msg->name);
    //  printf("%s\n", node->data.name);

        Insert_Last(head, node->data);

    }


    Node *tmp = head->next;

    while(tmp)
    {
        printf("插入链表姓名:%s\n", tmp->data.name);

        printf("插入链表套接字:%d\n", tmp->data.socket);
        tmp = tmp->next;
    }


    write (client_socket, msg, sizeof(struct Msg));

    sqlite3_close(db);

    return 0;
}

int Display(int client_socket, struct Msg *msg)//展示在线人员
{
    // char a[20];
    // strcpy(msg->msg, a);

    printf("测试:%d\n", msg->len);

    Node *tmp = head->next;

    int len = 0;
    while(tmp)
    {
        len++;
        tmp = tmp->next;
    }
    //求链表长度

    printf("长度:%d\n", len);

    //找出链表中的数据
    tmp = head->next;
    int i = 0;
    while(i < len)
    {
        //strcpy(msg->guys[i],tmp->data.name);
        msg->a[i] = tmp->data.socket;
        strcpy(msg->guys,tmp->data.name);

        tmp = tmp->next;
        i++;
        printf("套接字:%d\n", msg->a[0]);
        printf("姓名:%s\n", msg->guys);
        write (client_socket, msg, sizeof(struct Msg));
    }

//  msg->len = len;



//  write (client_socket, msg, sizeof(struct Msg));
}

int group_chat(int client_socket, struct Msg *msg)//群聊
{
    Node *tmp = head->next;

    while(tmp)
    {
        write(tmp->data.socket, msg, sizeof(struct Msg));
        tmp = tmp->next;
    }
}

int private_chat(int client_socket, struct Msg *msg)//私聊
{
    printf("%s 要给%s 发一条消息\n", msg->fromname, msg->toname);
    // && (strcmp(tmp->data.name, msg->toname) == 0)
    Node *tmp = head->next;
    while(tmp != NULL)
    {
        printf("11111111111111\n");
        if(strncmp(tmp->data.name, msg->toname,strlen(msg->toname) - 1) == 0)
        {
            write(tmp->data.socket, msg, sizeof(struct Msg));
            printf("套接字%d\n", tmp->data.socket);
            printf("11222222222221\n");
        }
        tmp = tmp->next;
    }
}

int Quit(int client_socket, struct Msg *msg)//退出登录
{
    printf("姓名:%s\n", msg->quitname);

    Node *tmp = head;
    while(tmp->next)
    {
        printf("222222222\n");
        if(strcmp(tmp->next->data.name, msg->quitname) == 0)
            break;

        tmp = tmp->next;
    }

    // if(tmp->next == NULL);
        // return FALSE;

//  printf("链表中姓名:%s\n", tmp->next->data.name);

    Node *p = tmp->next;
    tmp->next = p->next;
    free(p);
//  msg->cmd = 1006;
    printf("222222222\n");

    tmp = head->next;

    while(tmp)
    {
        printf("链表中姓名:%s\n", tmp->data.name);

        printf("链表中套接字:%d\n", tmp->data.socket);
        tmp = tmp->next;
    }

    write (client_socket, msg, sizeof(struct Msg));

    return TRUE;
}

int logout(int client_socket, struct Msg *msg)//注销用户
{
    printf("注销姓名%s\n", msg->logoutname);
    sqlite3 *db;
    int ret = sqlite3_open("chatroom.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("打开数据库失败\n");
        return -1;
    }

    printf("打开数据库成功\n");

    char *errmsg = NULL;
    char buf[100];

    sprintf(buf, "delete from login where name = '%s'", msg->logoutname);
    ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }
    else
    {
        printf("注销成功\n");
        msg->cmd = 1007;
    }

    write (client_socket, msg, sizeof(struct Msg));

    sqlite3_close(db);
    return 0;
}

int signature(int client_socket, struct Msg *msg)//展示签名
{
    sqlite3 *db;
    int ret = sqlite3_open("chatroom.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("打开数据库失败\n");
        return -1;
    }

    printf("打开数据库成功\n");

    char *errmsg = NULL;
    char **resultp;
    int nrow, ncolumn;
    char buf[100];
    sprintf(buf, "select sign from login where name = '%s'", msg->name);

    //在数据库中找出与传过来name对应的password
    ret = sqlite3_get_table(db, buf, &resultp, &nrow, &ncolumn, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("数据库操作失败:%s\n", errmsg);
        return -1;
    }

    strcpy(msg->sign, resultp[1]);

    write (client_socket, msg, sizeof(struct Msg));

    sqlite3_close(db);
    return 0;
}

int change_sign(int client_socket, struct Msg *msg)//修改个性签名
{
    sqlite3 *db;
    int ret = sqlite3_open("chatroom.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("打开数据库失败\n");
        return -1;
    }

    printf("打开数据库成功\n");

    char buf[100];
    char *errmsg = NULL;
    //改写数据库中的签名
    sprintf(buf, "update login set sign = '%s' where name = '%s'", msg->sign, msg->name);
    ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败:%s\n", errmsg);
        msg->cmd = -1;
        return -1;
    }
    else
    {
        printf("修改信息成功\n");
        msg->cmd = 1008;
    }
    //反馈结果给客户端
    write (client_socket, msg, sizeof(struct Msg));

    sqlite3_close(db);

    return 0;
}

int change_password(int client_socket, struct Msg *msg)//修改密码
{
    sqlite3 *db;
    int ret = sqlite3_open("chatroom.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("打开数据库失败\n");
        return -1;
    }

    printf("打开数据库成功\n");

    char buf[100];
    char *errmsg = NULL;
    //改写数据库中的签名
    sprintf(buf, "update login set password = '%s' where name = '%s'", msg->password, msg->name);
    ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("数据库操作失败:%s\n", errmsg);
        msg->cmd = -1;
        return -1;
    }
    else
    {
        printf("修改信息成功\n");
        msg->cmd = 1009;
    }
    //反馈结果给客户端
    write (client_socket, msg, sizeof(struct Msg));

    sqlite3_close(db);

    return 0;
}

int send_file(int client_socket, struct Msg *msg)//处理文件
{
    printf("%s 要给%s 发一条消息\n", msg->fromname, msg->toname);
    // && (strcmp(tmp->data.name, msg->toname) == 0)
    Node *tmp = head->next;
    while(tmp != NULL)
    {
    //  printf("11111111111111\n");
        if(strncmp(tmp->data.name, msg->toname,strlen(msg->toname) - 1) == 0)
        {
            write(tmp->data.socket, msg, sizeof(struct Msg));
            printf("套接字%d\n", tmp->data.socket);
        //  printf("11222222222221\n");
        }
        tmp = tmp->next;
    }
}

void* handle_client(void *v)//处理客户端消息控制台
{
    int client_socket = (int)v;
    struct Msg msg;

    while(1)
    {
        int ret = read(client_socket, &msg, sizeof(msg));
        if(ret == -1)
        {
            perror("read");
            break;
        }

        if(ret == 0)
        {
            printf("客户端退出\n");
            break;
        }

        switch(msg.cmd)
        {
            case 1 :   //注册
                reg(client_socket, &msg);
                break;
            case 2 :   //登录
                login(client_socket, &msg);
                break;
            case 3 :    //群聊
                group_chat(client_socket, &msg);
                break;
            case 4 :        //查看在线好友
                Display(client_socket, &msg);
                break;
            case 5 :
                private_chat(client_socket, &msg);
                break;
            case 6 :
                Quit(client_socket, &msg);
                break;
            case 7 :
                logout(client_socket, &msg);
                break;
            case 8 :
                change_sign(client_socket, &msg);
                break;
            case 9 :
                change_password(client_socket, &msg);
                break;
            case 10 :
                send_file(client_socket, &msg);
                break;
            case 20:
                signature(client_socket, &msg);
                break;
        }
    }
    close(client_socket);
}

int main()
{
    //初始化套接字
    int listen_socket = init_socket();

    head = Create_List();

    while(1)
    {
        //获取与客户端连接套接字
        int client_socket = Accept(listen_socket);

        pthread_t id;
        pthread_create(&id, NULL, handle_client, (void *)client_socket);
        pthread_detach(id);//线程分离

    }

    close(listen_socket);

    return 0;
}

客户端:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <time.h> 
#include <stdlib.h> 
#include <sqlite3.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PORT  9999

struct Msg
{
    int len;
    int a[20];
    char msg[1024];
    char name[20];
    char password[20];
    char guys[100];
    char toname[20];
    char fromname[20];
    char quitname[20];
    char logoutname[20];
    char sign[20];
    int cmd;
};

char Myname[20];


char* signature(int socketfd)
{
    struct Msg msg;
    msg.cmd = 20;

    strcpy(msg.name, Myname);
    write(socketfd, &msg, sizeof(msg));

    read(socketfd, &msg, sizeof(msg));

    char *buf = (char *)malloc(20);
    strcpy(buf, msg.sign);

    return buf;
}

void interface1()
{
    struct tm *ptr; 
    time_t lt; 
    lt =time(NULL); 
    ptr=gmtime(&lt);

    // char str[100];
    // strcpy(str, asctime(ptr));

    // int i = 0;
    // while(str[i] != '\n')
    // {
        // i++;
    // }
    // str[i] = '\0';

    printf("\t\t\t****************************************\n");
    printf("\t\t\t*");
    printf(asctime(ptr));
    printf("\t\t\t****************************************\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*             1、注册                  *\n");
    printf("\t\t\t*             2、登录                  *\n");
    printf("\t\t\t*             3、退出聊天室            *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t****************************************\n");
}

void interface2(char *buf)
{
    struct tm *ptr; 
    time_t lt; 
    lt =time(NULL); 
    ptr=gmtime(&lt);

     char str[100];
     strcpy(str, asctime(ptr));

     int i = 0;
     while(str[i] != '\n')
     {
         i++;
     }
     str[i] = '\0';

    printf("\t\t\t****************************************\n");
//  printf("\t\t\t*");
//  printf(asctime(ptr));
    printf("\t\t\t*%s   |=+=| :",str);
    printf("%s\n", buf);
    printf("\t\t\t****************************************\n");

    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
//  signature(socketfd);
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*            1、群聊                   *\n");
    printf("\t\t\t*            2、私聊                   *\n");
    printf("\t\t\t*            3、查看好友信息           *\n");
    printf("\t\t\t*            4、退出登录               *\n");
    printf("\t\t\t*            5、查看聊天记录           *\n");
    printf("\t\t\t*            6、注销用户               *\n");
    printf("\t\t\t*            7、修改个性签名           *\n");
    printf("\t\t\t*            8、修改密码               *\n");
    printf("\t\t\t*            9、文件传输               *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t*                                      *\n");
    printf("\t\t\t****************************************\n");
//  printf("\t\t\t9、文件传输\n");
}

void Display(int socketfd)//查看在线好友
{
    struct Msg msg;
    "qwe";
    msg.cmd = 4;
    msg.len = 1;
//  msg.msg = 
//  printf("1\n");
    printf("\t\t\t在线好友名单:\n");

    write(socketfd, &msg, sizeof(msg));

}

int read_file(struct Msg msg)//收文件
{
    int fd2 = open("2.txt", O_WRONLY|O_CREAT, 0777);
    if (fd2 == -1)
    {
        perror ("open fd2");
        return -1;
    }

    int ret = 0;
    char buf[1024] = {0};
    strcpy(buf, msg.msg);
//  printf("%s\n", msg.msg);




    write (fd2, buf, strlen(buf));
}

void* readMsg(void *v)//线程分离获取消息
{
    int socketfd = (int)v;
    struct Msg msg;
    while(1)
    {
        read(socketfd, &msg, sizeof(msg));
    //  printf("%d\n", msg.cmd);
        switch(msg.cmd)
        {
            case 3:     // 群聊
                printf("\t\t\t收到一条消息:%s\n", msg.msg);
                break;
            case 5:     // 私聊
                printf("\t\t\t%s给你发了一条消息:%s\n", msg.fromname, msg.msg);
                break;
            case 4:     // 查看在线人员
            //  printf("%d\n", msg.cmd);
            //  printf("在线好友名单:\n");
                printf("\t\t\t%s\n", msg.guys);
                break;
            case 6:
                printf("\t\t\t下线成功!\n");
                return;
            case 1007 :
                printf("\t\t\t注销成功!\n");
                return;             
            case 1008 :
                sleep(1);
                printf("\t\t\t修改个性签名成功!\n");
                break;
            case 1009 :
                sleep(1);
                printf("\t\t\t修改密码成功!\n");
                break;
            case 10 :
                read_file(msg);
                break;

        }
    }
}

int chat_records_all(struct Msg msg, int flag)//存储聊天信息
{

    struct tm *ptr; 
    time_t lt; 
    lt =time(NULL); 
    ptr=gmtime(&lt); 

    char str[100];
    strcpy(str, asctime(ptr));

//  int len = strlen(str);

    int i = 0;
    while(str[i] != '\n')
    {
        i++;
    }
    str[i] = '\0';

    int j = 0;
    while(msg.toname[j] != '\n')
    {
        j++;
    }
    msg.toname[j] = '\0';

    char pre[20];
    if(flag == 1)
    {
        strcpy(pre, "all");
    }
    else if(flag == 0)
    {
        strcpy(pre, msg.toname);
    }


//  printf("%s\n", pre);
    // printf(asctime(ptr)); 
    // printf(ctime(&lt)); 

    sqlite3 *db;
    int ret = sqlite3_open("chatrecords.db", &db);
    if(ret != SQLITE_OK)
    {
        printf("\t\t\t打开数据库失败\n");
        return -1;
    }

//  printf("打开数据库成功\n");

//  创建一张表records,用于存放群聊信息
    char *errmsg = NULL;
    char *sql = "create table if not exists records(time TEXT, fromname TEXT, toname TEXT, msg TEXT,primary key(time))";
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("\t\t\t数据库操作失败:%s\n", errmsg);
        return -1;
    }

    char buf[100];
//  将从收来的信息存放到数据库中
    sprintf(buf, "insert into records values('%s', '%s', '%s', '%s')", str, msg.fromname, pre, msg.msg);
    ret = sqlite3_exec(db, buf, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("\t\t\t数据库操作失败:%s\n", errmsg);
        return -1;
    }

    sqlite3_close(db);
}



void group_chat(int socketfd)//群聊
{
    struct Msg msg;
    msg.cmd = 3;
    printf("\t\t\t请输入要发送的内容:");

//  scanf("%s", msg.msg);
    fgets(msg.msg, 1024, stdin);
    strcpy(msg.fromname, Myname);
    write (socketfd, &msg, sizeof(msg));

    chat_records_all(msg, 1);
}

void private_chat(int socketfd)//私聊
{
    struct Msg msg;
    msg.cmd = 5;
    printf("\t\t\t请输入要发送对象的姓名:");
    fgets(msg.toname, 20, stdin);

    printf("\t\t\t请输入要发送的内容:");
    fgets(msg.msg, 1024, stdin);

    strcpy(msg.fromname, Myname);
    write (socketfd, &msg, sizeof(msg));

    chat_records_all(msg, 0);
}

void reg(int socketfd)//注册操作
{
    struct Msg msg;
    msg.cmd = 1;

    char name[20];
    char password[20];
    char sign[20];

    printf("\t\t\t请输入您的姓名:");
    scanf("%s", name);

    printf("\t\t\t请输入您的密码:", password);
    scanf("%s", password);

    printf("\t\t\t请输入您的个性签名:");
    scanf("%s", sign);

    strcpy(msg.name, name);
    strcpy(msg.password, password);
    strcpy(msg.sign, sign);

    write(socketfd, &msg, sizeof(msg));

    read(socketfd, &msg, sizeof(msg));

    if(msg.cmd == 1001)
    {
        printf("\t\t\t注册成功\n");
    }
    else if(msg.cmd == -1)
    {
        printf("\t\t\t注册失败\n");
    }

}

void Quit(int socketfd)//退出登录
{
    struct Msg msg;
    msg.cmd = 6;

    strcpy(msg.quitname, Myname);
    write(socketfd, &msg, sizeof(msg));

}

int view_records()//记录聊天记录
{
    sqlite3 *db;
    int ret = sqlite3_open("chatrecords.db", &db);
    if(ret != SQLITE_OK)
    {
        return -1;
    }

    char *errmsg = NULL;

    char **resultp;
    int nrow, ncolumn;
    char *sql = "select * from records";

    ret = sqlite3_get_table(db, sql, &resultp, &nrow, &ncolumn, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("\t\t\t数据库操作错误:%s\n", errmsg);
        return  -1;
    }

    int i;
//  printf("nrow = %d, ncolume = %d\n", nrow, ncolumn);

    for(i = 0; i < (nrow + 1) * ncolumn; i++)
    {
        if(i % ncolumn == 0)
        {
            printf("\n");
        }

        printf("%-28s", resultp[i]);
    }

    printf("\n");

    sqlite3_close(db);
}

void logout(int socketfd)//注销账户
{
    struct Msg msg;
    msg.cmd = 7;

    strcpy(msg.logoutname, Myname);
    write(socketfd, &msg, sizeof(msg));
}

void change_sign(socketfd)//修改个性签名
{
    struct Msg msg;
    msg.cmd = 8;

    char sign[20];

    printf("\t\t\t请输入您的新个性签名:");
    scanf("%s", sign);

    strcpy(msg.name, Myname);

    strcpy(msg.sign, sign);

    write(socketfd, &msg, sizeof(msg));
}

void change_password(socketfd)//修改密码
{
    struct Msg msg;
    msg.cmd = 9;

    char password[20];

    printf("\t\t\t请输入您的新密码:");
    scanf("%s", password);

    strcpy(msg.name, Myname);

    strcpy(msg.password, password);

    write(socketfd, &msg, sizeof(msg));
}

int send_file(int socketfd)// 发送文件
{
    struct Msg msg;
    msg.cmd = 10;

    printf("\t\t\t当前目录下文件\n");
     char name[20];
     char ptr[20];
    // scanf("%s", ch);
    // if(ch == "y")
    // {
        system("ls");
        printf("请选择你想发送的文件:");
        scanf("%s", ptr);


        int fd1 = open(ptr, O_RDWR);
        if(fd1 == -1)
        {
            perror("open");
            return -1;
        }


        char buf[1024] = {0};

        int ret = read(fd1, buf, 1023);
        buf[ret] = '\0';
//      printf("%s\n", buf);
        strcpy(msg.msg, buf);

        printf("\t\t\t请输入您要发送的对象:");
//      fgets(msg.toname, 20, stdin);
        scanf("%s", name);
        strcpy(msg.toname, name);

        strcpy(msg.fromname, Myname);

    //  printf("%s\n", msg.msg);
        write(socketfd, &msg, sizeof(msg));
    // }
    // else
    // {
        // return;
    // }
}

void oper(int socketfd, char *buf)//服务选择2
{
    while(1)
    {
        system("clear");
        interface2(buf);
        char ch[2];
        printf("\t\t\t请输入操作:");

        scanf("%s",ch);
    //  fgets(ch, 2, stdin);
        while(getchar()!= '\n');
    //  printf("ch[0]%c123 \n",ch[0]);
    //  printf("1\n");

        if(strcmp(ch, "1") == 0)
        {
            group_chat(socketfd);
            sleep(1);
            printf("\t\t\t您可以按ENTER继续您想要的操作!\n");
            getchar();
            getchar();
        }
        else if(strcmp(ch, "2") == 0)
        {
            private_chat(socketfd);
            sleep(1);
            printf("\t\t\t您可以按ENTER继续您想要的操作!\n");
            getchar();
            getchar();
        }
        else if(strcmp(ch, "3") == 0)
        {
            printf("\t\t\t查找中........\n");
            sleep(1);
            Display(socketfd);
            sleep(1);
            printf("\t\t\t您可以按ENTER继续您想要的操作!\n");
            getchar();
            getchar();
        }
        else if(strcmp(ch, "4") == 0)
        {
            printf("\t\t\t下线中........\n");
            sleep(1);
            Quit(socketfd);
            sleep(1);
            break;
        }
        else if(strcmp(ch, "5") == 0)
        {
            printf("\t\t\t查询中............\n");
            sleep(1);
            view_records();
            sleep(1);
            printf("\t\t\t您可以按ENTER继续您想要的操作!\n");
            getchar();
            getchar();
        }
        else if(strcmp(ch, "6") == 0)
        {
            printf("\t\t\t注销中........\n");
            sleep(1);
            logout(socketfd);
            sleep(1);
            Quit(socketfd);
            sleep(1);
            break;
        }
        else if(strcmp(ch, "7") == 0)
        {
            change_sign(socketfd);
            printf("\t\t\t修改中........\n");
            sleep(2);

            printf("\t\t\t您可以按ENTER继续您想要的操作!\n");
            getchar();
            getchar();
        }
        else if(strcmp(ch, "8") == 0)
        {
            change_password(socketfd);
            printf("\t\t\t修改中........\n");
            sleep(1);
            sleep(1);
            printf("\t\t\t您可以按ENTER继续您想要的操作!\n");
            getchar();
            getchar();
        }
        else if(strcmp(ch, "9") == 0)
        {
            send_file(socketfd);
        }
    }
}

void login(int socketfd)//登录操作
{
    struct Msg msg;
    msg.cmd = 2;

//  char Myname[20];
    char password[20];


    printf("\t\t\t请输入您的姓名:");
    scanf("%s", Myname);
//  while(getchar()!= '\n');

    printf("\t\t\t请输入您的密码:");
    scanf("%s", password);


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

    strcpy(msg.name, Myname);
    strcpy(msg.password, password);


    write(socketfd, &msg, sizeof(msg));

    read(socketfd, &msg, sizeof(msg));

//  printf("%d\n", msg.cmd);
//  printf("%s\n", signature(socketfd));
    char buf[20];
    strcpy(buf, signature(socketfd));
//  printf("%s\n", buf);

    if(msg.cmd == 1002)
    {   
        printf("\t\t\t登录成功\n");

        pthread_t id;
        pthread_create(&id, NULL, readMsg, (void *)socketfd);
        pthread_detach(id);

        oper(socketfd, buf);
    }
    else if(msg.cmd == -1)
    {
        printf("\t\t\t登录失败!\n");
    }
    else if(msg.cmd == -2)
    {
        printf("\t\t\t不存在该用户!\n");
    }


}

void ask_server(int socketfd)//服务选择
{
    char ch[2];

    while (1)
    {
        system("clear");
        interface1();
        printf("\t\t\t请输入您想进行的操作:");
        scanf("%s", ch);
        while(getchar() != '\n');

        if(strcmp(ch, "1") == 0)
        {
            reg(socketfd);
        }
        else if(strcmp(ch, "2") == 0)
        {
            login(socketfd);
        }
        else if(strcmp(ch, "3") == 0)
        {
            break;
        }
    //  system("clear");
    }
}

int main()
{
    //创建与服务器通信的套接字
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if(socketfd == -1)
    {
        perror("socket");
        return -1;
    }

    //连接服务器
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    inet_aton("127.0.0.1", &(addr.sin_addr));

    //连接服务器,如果成功,发挥0,如果失败,返回-1
    //成功则可以通过socketfd与服务器进行通信
    int ret = connect(socketfd, (struct sockaddr *)&addr, sizeof(addr));
    if(ret == -1)
    {
        perror("connect");
        return -1;
    }

//  printf("\t\t\t成功连上服务器\n");

    ask_server(socketfd);

    close(socketfd);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/dxd_123456/article/details/78369771