Linux下基于UDP协议实现的聊天室项目(附源码)
2018-01-02 15:58
381 查看
好久没来更新了,这段时间一直在着手完成这个项目,由于之前没有接触过这种稍大型的项目,而且对于C/S架构以及UDP通信的了解也不是很深,所以前面很大的一段时间都被浪费掉了,做了很大无用功。
刚开始弄的时候,也是在网上搜了很多资料,找了很多版本,发现大都有一个问题,就是旁人看起来不易理解 ,代码注释行有限,导致看起来一头雾水。所以,本文将会花点篇幅来理清思路(本文使用的是UDP协议进行通信,相对于使用TCP协议的通信方式不同,不过思路大致相同)。
下面先大致了解一下基本功能
聊 天 室 项 目 功 能
1. 采用 Client/Server 架构
2. Client A 登陆聊天服务器前,需要注册自己的 ID 和密码
3. 注册成功后,Client A 就可以通过自己的 ID 和密码登陆聊天服务器
4. 多个 Client X 可以同时登陆聊天服务器之后,与其他用户进行通讯聊天
5. Client A 成功登陆后可以查看当前聊天室内其他在线用户 Client x
6. Client A 可以选择发消息给某个特定的 Client X,即”悄悄话”功能
7. Client A 可以选择发消息全部的在线用户,即”群发消息”功能
8. Client A 在退出时需要保存聊天记录
9. Server 端维护一个所有登陆用户的聊天会的记录文件,以便备查
可以选择实现的附加功能:
1. Server 可以内建一个特殊权限的账号 admin,用于管理聊天室
2. Admin 可以将某个 Client X “踢出聊天室”
3. Admin 可以将某个 Client X ”设为只能旁听,不能发言”
4. Client 端发言增加表情符号,可以设置某些自定义的特殊组合来表达感
情.如输入:),则会自动发送”XXX 向大家做了个笑脸”
这个项目大家可以参考QQ的功能不断进行完善,有很多小功能都可以自己添加,比如,本文添加了点赞和个性签名以及修改个签的功能,总之,大伙可以根据兴趣或需求自行添加。
[b]********************************[/b]前方高能[b]****************************[/b]
思 路 整 理
说明:本人完成这个项目总共使用了三个文件,头文件(UDP_chatroom.h)、服务器端(UDP_Server.c)、客户端(UDP_Client.c)。
1.第一步当然是搭建通信环境了,具体在上一篇博文中讲述过了
http://blog.csdn.net/hua12134/article/details/78797328
此处不再赘述。
2.理清功能,我们看一下这些基本功能:注册、登入、私聊、群聊、点赞、发表情、查看记录balabala, 我们可以将这些功能分为两大块:登入前和登入后。登入前就包括注册和登入以及退出客户端, 登入后就包括私聊群聊那些功能了。所以,首先要解决的就是注册和登入。
3.想想我们平时注册账号需要哪些东西,用户名、账号以及密码,对吧(有兴趣可以添加忘记密码、密保或者添加手机号和邮箱等功能),当我们注册好了之后,肯定是需要保存下来的,所以需要用到数据库进行保存,而数据库只能放在服务器这端,只能服务器才能访问。客户端首先给服务器发送一个注册请求,服务器收到请求之后开始查询数据库,如果该账号没有被注册过,则将该客户端发来的注册信息写入数据库并反馈一个消息给该客户端注册成功,否则反馈给客户端重新注册。这样,注册就算完成了。
4.接下来就是登入,首先还是客户端给服务器发送一个登入请求,服务器收到请求之后开始查询数据库,如果查询到的账号和密码与客户端发送过来的都一致,则允许登入并反馈给客户端登入成功。这个地方要分三种情况讨论:账号密码都正确、账号或密码不正确、账号不存在(即未注册)。
5.注册登入完成之后就是登入后的功能了,需要注意的是,前面的注册和登入都是只有一个客户端与服务器通信,只需要相互发送和接收消息即可。但是登入之后可能需要一个服务器与多个客户端通信,比如,私聊功能,客户端A要与客户端B私聊,A给B发送消息,首先A将要发送的消息以及B的地址给服务器,服务器再根据地址将消息转发给B。那么,A又怎么知道B的地址呢,所以这就需要绑定了,将客户端的用户名与地址绑定,这样一来,A只需要知道B的用户名即可。同时,服务器还需反馈给客户端A发送成功还是失败。也就是说,如果A给B发送一个消息,实际上是,A给服务器发送一条信息,然后,服务器给A和B发送消息。再比如,点赞功能,A给B点赞,A发送请求给服务器,服务器查询数据库,发现数据库中有B这个人,只需要给B的赞数加一即可,然后反馈给A点赞成功,同时给B发送一天提醒消息,告诉B,A给你点赞了。同样的,禁言、解禁以及踢人都类似。。而有些功能,比如,修改个性签名,就像当初的注册登入一样,只需要一个客户端与服务器交流即可,A给服务器发送请求,服务器收到请求后开始查询数据库,找到A的个性签名这一栏并修改,然后将结果反馈给A即可。
从上面可以看出,客户端自己什么也干不了,它想干什么事,必须先发请求给服务器,所以,在服务器端必须有专门接收客户端请求的,使用recefrom函数,可以放在main函数里面,发送消息使用sendto函数放在功能函数里面。在客户端,需要发送不同的请求以及接收服务器发来的消息或反馈,可以起两个线程,一个发送,一个接收,也可以只起一个线程用来接收,而发送就直接交给本进程完成。(本文中客户端只起一个线程,服务器端不起线程)
还需要注意,以上的私聊群聊点赞等等,这些功能需要对方在线才能完成,所以,需要建立一个链表来对在线用户进行管理
接下来,我们再来梳理一下客户端和服务器发送和接收的结构体里面有哪些成员以及服务器端的数据库需要保存哪些东西,如果不理解这两者的区别与作用,很容易将两者混淆。我们先在脑海中憧憬一下,首先我们运行客户端,出来一个界面,注册登入和退出(忘记密码可自行添加),登入后又有一个界面,群聊私聊点赞等等许多功能。能跟我们交互的只有客户端对吧,比如我们选择注册,只需要在客户端来个switch case,选择’1’即可,可是对于服务器来说,它要怎么理解来着客户端的这个请求呢?其实很简单,只需要我们在客户端发送给服务器的结构体中添加一个成员cmd即可,这样,客户端只需要给这个SendBuf.cmd赋值就可以了,赋的值其实是一个宏,可以在头文件中预先宏定义,但是尽量有一定的含义(便于理解与可读性),比如,注册的话,可以SendBuf.cmd = RegAcc; 这里的RegAcc就是一个宏,取名含义就是注册账号。其他的都类似这样处理。然后等服务器端处理完这些请求后,需要返回一个结果给客户端,所以在服务器的SendBuf里应该有一个result的成员来反馈结果。
这样看来,客户端发给服务器接收的结构体和服务器发给客户端接收的结构体,两者的成员并不是相同的,那么客户端和服务器每端都需要两个结构体吗?这样是可以的,但是这样一来就有四个结构体了,对于后面的处理可能就容易乱。所以,我们可以将发送和接收用同一个结构体。需要注意的是结构体涉及到结构体大小的问题,所以需要客户端和服务器两端的结构体完全一致,即成员顺序必须一致。
结构体的成员大致就这些了,接下来,我们来看看数据库里面有哪些内容,我们知道,数据库是用来保存用户信息的,所以用户的基本信息是需要的,用户名、账号、密码、VIP、赞数、个签,甚至还可以有密保等内容,这些都是为了保证用户登入以及登入后该用户之前的信息没有丢失。所以不要讲这些东西与结构体中的成员混淆了。
源码(并非很完善,仅供参考)
刚开始弄的时候,也是在网上搜了很多资料,找了很多版本,发现大都有一个问题,就是旁人看起来不易理解 ,代码注释行有限,导致看起来一头雾水。所以,本文将会花点篇幅来理清思路(本文使用的是UDP协议进行通信,相对于使用TCP协议的通信方式不同,不过思路大致相同)。
下面先大致了解一下基本功能
聊 天 室 项 目 功 能
1. 采用 Client/Server 架构
2. Client A 登陆聊天服务器前,需要注册自己的 ID 和密码
3. 注册成功后,Client A 就可以通过自己的 ID 和密码登陆聊天服务器
4. 多个 Client X 可以同时登陆聊天服务器之后,与其他用户进行通讯聊天
5. Client A 成功登陆后可以查看当前聊天室内其他在线用户 Client x
6. Client A 可以选择发消息给某个特定的 Client X,即”悄悄话”功能
7. Client A 可以选择发消息全部的在线用户,即”群发消息”功能
8. Client A 在退出时需要保存聊天记录
9. Server 端维护一个所有登陆用户的聊天会的记录文件,以便备查
可以选择实现的附加功能:
1. Server 可以内建一个特殊权限的账号 admin,用于管理聊天室
2. Admin 可以将某个 Client X “踢出聊天室”
3. Admin 可以将某个 Client X ”设为只能旁听,不能发言”
4. Client 端发言增加表情符号,可以设置某些自定义的特殊组合来表达感
情.如输入:),则会自动发送”XXX 向大家做了个笑脸”
这个项目大家可以参考QQ的功能不断进行完善,有很多小功能都可以自己添加,比如,本文添加了点赞和个性签名以及修改个签的功能,总之,大伙可以根据兴趣或需求自行添加。
[b]********************************[/b]前方高能[b]****************************[/b]
思 路 整 理
说明:本人完成这个项目总共使用了三个文件,头文件(UDP_chatroom.h)、服务器端(UDP_Server.c)、客户端(UDP_Client.c)。
1.第一步当然是搭建通信环境了,具体在上一篇博文中讲述过了
http://blog.csdn.net/hua12134/article/details/78797328
此处不再赘述。
2.理清功能,我们看一下这些基本功能:注册、登入、私聊、群聊、点赞、发表情、查看记录balabala, 我们可以将这些功能分为两大块:登入前和登入后。登入前就包括注册和登入以及退出客户端, 登入后就包括私聊群聊那些功能了。所以,首先要解决的就是注册和登入。
3.想想我们平时注册账号需要哪些东西,用户名、账号以及密码,对吧(有兴趣可以添加忘记密码、密保或者添加手机号和邮箱等功能),当我们注册好了之后,肯定是需要保存下来的,所以需要用到数据库进行保存,而数据库只能放在服务器这端,只能服务器才能访问。客户端首先给服务器发送一个注册请求,服务器收到请求之后开始查询数据库,如果该账号没有被注册过,则将该客户端发来的注册信息写入数据库并反馈一个消息给该客户端注册成功,否则反馈给客户端重新注册。这样,注册就算完成了。
4.接下来就是登入,首先还是客户端给服务器发送一个登入请求,服务器收到请求之后开始查询数据库,如果查询到的账号和密码与客户端发送过来的都一致,则允许登入并反馈给客户端登入成功。这个地方要分三种情况讨论:账号密码都正确、账号或密码不正确、账号不存在(即未注册)。
5.注册登入完成之后就是登入后的功能了,需要注意的是,前面的注册和登入都是只有一个客户端与服务器通信,只需要相互发送和接收消息即可。但是登入之后可能需要一个服务器与多个客户端通信,比如,私聊功能,客户端A要与客户端B私聊,A给B发送消息,首先A将要发送的消息以及B的地址给服务器,服务器再根据地址将消息转发给B。那么,A又怎么知道B的地址呢,所以这就需要绑定了,将客户端的用户名与地址绑定,这样一来,A只需要知道B的用户名即可。同时,服务器还需反馈给客户端A发送成功还是失败。也就是说,如果A给B发送一个消息,实际上是,A给服务器发送一条信息,然后,服务器给A和B发送消息。再比如,点赞功能,A给B点赞,A发送请求给服务器,服务器查询数据库,发现数据库中有B这个人,只需要给B的赞数加一即可,然后反馈给A点赞成功,同时给B发送一天提醒消息,告诉B,A给你点赞了。同样的,禁言、解禁以及踢人都类似。。而有些功能,比如,修改个性签名,就像当初的注册登入一样,只需要一个客户端与服务器交流即可,A给服务器发送请求,服务器收到请求后开始查询数据库,找到A的个性签名这一栏并修改,然后将结果反馈给A即可。
从上面可以看出,客户端自己什么也干不了,它想干什么事,必须先发请求给服务器,所以,在服务器端必须有专门接收客户端请求的,使用recefrom函数,可以放在main函数里面,发送消息使用sendto函数放在功能函数里面。在客户端,需要发送不同的请求以及接收服务器发来的消息或反馈,可以起两个线程,一个发送,一个接收,也可以只起一个线程用来接收,而发送就直接交给本进程完成。(本文中客户端只起一个线程,服务器端不起线程)
还需要注意,以上的私聊群聊点赞等等,这些功能需要对方在线才能完成,所以,需要建立一个链表来对在线用户进行管理
接下来,我们再来梳理一下客户端和服务器发送和接收的结构体里面有哪些成员以及服务器端的数据库需要保存哪些东西,如果不理解这两者的区别与作用,很容易将两者混淆。我们先在脑海中憧憬一下,首先我们运行客户端,出来一个界面,注册登入和退出(忘记密码可自行添加),登入后又有一个界面,群聊私聊点赞等等许多功能。能跟我们交互的只有客户端对吧,比如我们选择注册,只需要在客户端来个switch case,选择’1’即可,可是对于服务器来说,它要怎么理解来着客户端的这个请求呢?其实很简单,只需要我们在客户端发送给服务器的结构体中添加一个成员cmd即可,这样,客户端只需要给这个SendBuf.cmd赋值就可以了,赋的值其实是一个宏,可以在头文件中预先宏定义,但是尽量有一定的含义(便于理解与可读性),比如,注册的话,可以SendBuf.cmd = RegAcc; 这里的RegAcc就是一个宏,取名含义就是注册账号。其他的都类似这样处理。然后等服务器端处理完这些请求后,需要返回一个结果给客户端,所以在服务器的SendBuf里应该有一个result的成员来反馈结果。
这样看来,客户端发给服务器接收的结构体和服务器发给客户端接收的结构体,两者的成员并不是相同的,那么客户端和服务器每端都需要两个结构体吗?这样是可以的,但是这样一来就有四个结构体了,对于后面的处理可能就容易乱。所以,我们可以将发送和接收用同一个结构体。需要注意的是结构体涉及到结构体大小的问题,所以需要客户端和服务器两端的结构体完全一致,即成员顺序必须一致。
结构体的成员大致就这些了,接下来,我们来看看数据库里面有哪些内容,我们知道,数据库是用来保存用户信息的,所以用户的基本信息是需要的,用户名、账号、密码、VIP、赞数、个签,甚至还可以有密保等内容,这些都是为了保证用户登入以及登入后该用户之前的信息没有丢失。所以不要讲这些东西与结构体中的成员混淆了。
源码(并非很完善,仅供参考)
/*************************************************** 20000 File name: UDP_chatroom.h Author:華仔 Data:2017.12.25 Description:聊天室头文件 ***************************************************/ #ifndef _CHATROOM_H_ #define _CHATROOM_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlite3.h> #include <sys/types.h> #include <sys/socket.h> #include <signal.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <signal.h> #include <pthread.h> #include <semaphore.h> #include <termios.h> #include <time.h> #include <sys/stat.h> #include <fcntl.h> /*********************注册登录**********************************/ #define REG 1 //注册 #define LOG 2 //登录 #define FORGET 3 //忘记密码 #define EXIT 4 //退出 #define EXISTING_ACC 5 //账号已存在 #define LOGGED_ACC 6 //账号已登录 #define ERROR 7 //账号或密码错误 #define LOG_SUCCESS 8 //登录成功 #define REG_SUCCESS 9 //注册成功 #define Exit 10 //下线 /***************************************************************/ /******************聊天室功能***********************************/ #define private_chat 11 //私聊 #define group_chat 12 //群聊 #define group_result 13 //群聊接受 #define file_transfer 14 //文件传输 #define online 15 //查看在线人数 #define expression 16 //表情 #define phrases 17 //常用语 #define motto 18 //个性签名 #define motto_change 19 //更改个性签名 #define like 20 //点赞 #define Vip 21 //开会员 #define Shutup 22 //禁言 #define lifted 23 //解禁 #define kick 24 //踢人 /***************************************************************/ /****************服务器返回结果*********************************/ #define VIP_SUCCESS 25 //开会员成功 #define SHUTUP_SUCCESS 26 //禁言成功 #define SEND_SUCCESS 27 //发送成功 #define SEND_FAILED 28 //操作失败 #define KICK_SUCCESS 30 //踢人成功 #define LIKE_SUCCESS 31 //点赞成功 #define CHANGE_SUCCESS 32 //更改个性签名成功 /***************************************************************/ #endif
/*************************************************** File name: UDP_server.c Author:華仔 Data:2017.12.25 Description:聊天软件服务器端 ***************************************************/ #include "UDP_chatroom.h" #define PORT 8888 typedef struct info { char username[20]; //用户名 char account[20]; //账号 char passwd[20]; //密码 char from_name[20]; //发信人 char to_name[20]; //收信人 char moto[30]; //个性签名 char online_name[20][20]; //在线人名 int online_num; //在线人数 int cmd; //提取操作符 int vip; //会员标志 int likes; //点赞数 int result; //返回操作结果 char msg[1024]; //发送、接收消息 char e_s; //确认发送的表情 char p_s; //确认发送的常用语 char file_name[50]; //文件名 char Ftp[2048]; //文件传输 }Info; typedef struct node { struct sockaddr_in client_addr; char name[20]; char account[20]; struct node *next; }Node, *LinkList; struct sockaddr_in client_addr; Info SendBuf; Info RecvBuf; sqlite3 *ppdb = NULL; //数据库 LinkList head = NULL; //在线用户 int sockfd; int ret; //注册 void deal_reg(struct sockaddr_in temp_addr) { char sql[100] = {0}; sprintf(sql, "insert into chatroom(username, account, passwd, likes, vip) values('%s','%s','%s','%d','%d')",RecvBuf.username, RecvBuf.account, RecvBuf.passwd, RecvBuf.likes, RecvBuf.vip); char *errmsg = NULL; ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg); if(ret != SQLITE_OK) { perror("sqlite3_exec2"); SendBuf.result = EXISTING_ACC; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_server_log"); exit(1); } return; } SendBuf.result = REG_SUCCESS; printf("注册信息:用户名:%s \t 账号:%s \t 密码:%s\n", RecvBuf.username, RecvBuf.account, RecvBuf.passwd); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_server_register"); exit(1); } bzero(&SendBuf, sizeof(SendBuf)); } //登入 void deal_log(struct sockaddr_in temp_addr) { char **Result = NULL; int nRow; //行数 int nColumn; //列数 int ret; char sql[100] = {0}; sprintf(sql, "select username, passwd, likes, vip, moto from chatroom where account = '%s' and passwd = '%s'", RecvBuf.account, RecvBuf.passwd); ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, NULL); if (ret != SQLITE_OK) { perror("sqlite3_get_table_deal_log"); exit(1); } if(1 == nRow) { LinkList tmp = head->next; while(tmp != head) { if(!strcmp(tmp->account,RecvBuf.account)) { SendBuf.result = LOGGED_ACC; //已登入 ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_server_log"); exit(1); } return; } tmp = tmp->next; } SendBuf.result = LOG_SUCCESS; //登入成功 LinkList p =(LinkList)malloc(sizeof(Node)); if(p == NULL) { printf("malloc error!\n"); return; } strcpy(p->account,RecvBuf.account); strcpy(p->name, Result[5]); strcpy(SendBuf.username,Result[5]); SendBuf.vip = *(Result[8]) - 48; SendBuf.likes = *(Result[7]) - 48; // strcpy(SendBuf.moto, Result[9]); p->client_addr.sin_family = temp_addr.sin_family; p->client_addr.sin_port = temp_addr.sin_port; p->client_addr.sin_addr.s_addr = temp_addr.sin_addr.s_addr; printf("%s 上线!\n",Result[5]); printf("登入信息:用户名:%s \t 账号:%s \t 密码:%s \t 端口号:%d\n",SendBuf.username, p->account, RecvBuf.passwd, p->client_addr.sin_port); p->next = head->next; head->next = p; } else { SendBuf.result = ERROR; } ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_server_log"); exit(1); } } //私聊 int deal_private(struct sockaddr_in temp_addr) { int flag = 0; LinkList tmp = head->next; while(tmp != head) { if(!strcmp(tmp->name,RecvBuf.to_name)) { flag = 1; strcpy(SendBuf.msg, RecvBuf.msg); strcpy(SendBuf.from_name,RecvBuf.username); SendBuf.result = private_chat; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if(ret == -1) { perror("sendto_pchat"); exit(1); } break; } tmp=tmp->next; } if(flag) { SendBuf.result = SEND_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_success"); exit(1); } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_failure"); exit(1); } } } //群聊 int deal_group(struct sockaddr_in temp_addr) { int flag = 0; LinkList tmp = head->next; while (tmp != head) { if (tmp->client_addr.sin_port != temp_addr.sin_port) { flag = 1; SendBuf.result = group_chat; strcpy(SendBuf.from_name, RecvBuf.username); // printf("%s\n",SendBuf.from_name); strcpy(SendBuf.msg, RecvBuf.msg); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if (ret < 0) { perror("sendto_group_chat"); exit(1); } } tmp = tmp->next; } if (flag) { SendBuf.result = SEND_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_group_chat_success"); exit(1); } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_group_chat_failure"); exit(1); } } } //查看在线人数 int deal_online(struct sockaddr_in temp_addr) { int i = 0; SendBuf.online_num = 0; LinkList tmp = head->next; while(tmp != head) { SendBuf.online_num++; strcpy(SendBuf.online_name[i],tmp->name); i++; tmp = tmp->next; } SendBuf.result = online; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_online"); } } //点赞 int deal_like(struct sockaddr_in temp_addr) { char *errmsg = NULL; char **Result = NULL; int nRow; int nColumn; char sql[100]; sprintf(sql, "select likes from chatroom where username = '%s'", RecvBuf.to_name); ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, &errmsg); if(ret != SQLITE_OK) { printf("select fail:%d(%s)\n", ret, errmsg); return -1; } if(nRow == 1) { sprintf(sql, "update chatroom set likes = %d where username = '%s'", *(Result[1]) - 47, RecvBuf.to_name); ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg); if(ret != SQLITE_OK) { printf("update fail:%d(%s)\n", ret, errmsg); return ; } LinkList tmp = head->next; while(tmp != head) //遍历数据库,找到用户 { if(strcmp(tmp->name, RecvBuf.to_name) == 0) { SendBuf.likes = *(Result[1]) - 47; SendBuf.result = like; strcpy(SendBuf.from_name,RecvBuf.username); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if(ret == -1) { perror("sendto_like"); } break; } tmp = tmp->next; } SendBuf.result = LIKE_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_like_suuess"); } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_like_failed"); } } } //发送表情(群发) int deal_expression(struct sockaddr_in temp_addr) { int flag = 0; LinkList tmp = head->next; while (tmp != head) { if (tmp->client_addr.sin_port != temp_addr.sin_port) { flag = 1; SendBuf.result = expression; strcpy(SendBuf.from_name, RecvBuf.username); SendBuf.e_s = RecvBuf.e_s; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if (ret < 0) { perror("sendto_face"); exit(1); } } tmp = tmp->next; } if (flag) { SendBuf.result = SEND_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_face_success"); exit(1); } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_face_failure"); exit(1); } } } //发送常用语(私发) int deal_phrases(struct sockaddr_in temp_addr) { int flag = 0; LinkList tmp = head->next; while(tmp != head) { if(strcmp(tmp->name,RecvBuf.to_name) == 0 ) { flag = 1; SendBuf.result = phrases; SendBuf.p_s = RecvBuf.p_s; strcpy(SendBuf.from_name,RecvBuf.username); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if(ret == -1) { perror("sendto_useful"); exit(1); } break; } tmp=tmp->next; } if(flag) { //memset(SendBuf.result,0,sizeof(SendBuf.result)); SendBuf.result = SEND_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_success"); exit(1); } //printf("%s send message to %s ...\n",userIn.name,userIn.toname); } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_failure"); exit(1); } //printf("%s send error...\n",userIn.name); } } //注册会员 void deal_vip(struct sockaddr_in temp_addr) { char sql[100] = {0}; sprintf(sql,"update chatroom set vip= %d where username = '%s';",RecvBuf.vip,RecvBuf.username); printf("%s 成为VIP\n",RecvBuf.username); ret = sqlite3_exec(ppdb,sql,NULL,NULL,NULL); if(ret!=SQLITE_OK) { perror("sqlite3_exec_vip"); return; } SendBuf.vip = 1; SendBuf.result = VIP_SUCCESS; strcpy(SendBuf.username , RecvBuf.username); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_vip_failure"); exit(1); } } //文件传输 void deal_ftp(struct sockaddr_in temp_addr) { int flag = 0; LinkList tmp = head->next; while (tmp != head) { if (strcmp(tmp->name,RecvBuf.to_name) == 0) { flag = 1; strcpy(SendBuf.from_name,RecvBuf.username); strcpy(SendBuf.file_name, RecvBuf.file_name);//拷贝文件名 strcpy(SendBuf.Ftp, RecvBuf.Ftp);//拷贝文件内容 SendBuf.result = file_transfer; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if (ret < 0) { perror("sendto_sendfile"); exit(1); } } tmp = tmp->next; } if (1 == flag) { SendBuf.result = SEND_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_file_success"); exit(1); } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_file_failure"); exit(1); } } } //禁言 int deal_shutup(struct sockaddr_in temp_addr) { LinkList tmp = head->next; int flag = 0; while(tmp != head) { if(strcmp(tmp->name,RecvBuf.to_name)==0) { flag = 1; SendBuf.result = Shutup; strcpy(SendBuf.from_name,RecvBuf.username); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if (ret < 0) { perror("sendto_deal_shutup"); return; } } tmp = tmp->next; } if(flag) { SendBuf.result = SHUTUP_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_shutup_success"); return; } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_shutup_failure"); return; } } } //踢人 int deal_kick(struct sockaddr_in temp_addr) { int flag = 0; LinkList tmp = head->next; while(tmp != head) { if(strcmp(tmp->name, RecvBuf.to_name ) == 0) { flag = 1; SendBuf.result = kick; strcpy(SendBuf.from_name,RecvBuf.username); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr)); if (ret < 0) { perror("sendto_kick"); return; } /* LinkList q = tmp->next; tmp->next = q->next; free(q); */ printf("%s 下线!\n", RecvBuf.to_name ); break; } tmp = tmp->next; } if(flag == 1) { SendBuf.result = KICK_SUCCESS; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_kick_success"); exit(1); } } else { SendBuf.result = SEND_FAILED; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if (ret < 0) { perror("sendto_kick_failed"); exit(1); } } } //下线 int deal_quit(struct sockaddr_in temp_addr) { LinkList tmp = head; /* if(tmp->next->next == head) { if(strcmp(tmp->next->name, RecvBuf.username ) == 0) { LinkList p = tmp->next; tmp->next = p->next; free(p); printf("%s 下线!\n", RecvBuf.username ); return; } tmp = tmp->next; } */ printf("name : %s\n", RecvBuf.username); while(tmp->next != head) { if(strcmp(tmp->next->name, RecvBuf.username ) == 0) { LinkList q = tmp->next; tmp->next = q->next; free(q); printf("%s 下线!\n", RecvBuf.username ); break; } tmp = tmp->next; } ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr)); if(ret == -1) { perror("sendto_quit"); } return 0; } int main() { struct sockaddr_in server_addr; struct sockaddr_in client_addr; int length; int flag; char sql[100] = {0}; head = (LinkList)malloc(sizeof(Node)); if (NULL == head) { printf("Malloc Failure!\n"); return; } head->next = head; sockfd = socket(PF_INET, SOCK_DGRAM, 0); if (-1 == sockfd) { perror("socket"); exit(1); } bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = PORT; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("bind"); exit(1); } ret = sqlite3_open("chatroom.db", &ppdb); if (ret != SQLITE_OK) { perror("sqlite3_open"); exit(1); } sprintf(sql, "create table if not exists chatroom (username text, account text primary key, passwd text ,likes integer, vip text, moto text);"); ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); if (ret != SQLITE_OK) { perror("sqlite3_exec1"); exit(1); } while (1) { bzero(&SendBuf, sizeof(SendBuf)); length = sizeof(client_addr); ret = recvfrom(sockfd, &RecvBuf, sizeof(RecvBuf), 0, (struct sockaddr *)&client_addr, &length); if (ret < 0) { perror("recvfrom"); exit(1); } switch (RecvBuf.cmd) { case (REG): //注册 { deal_reg(client_addr); break; } case (LOG): //登录 { deal_log(client_addr); break; } case (EXIT): //退出 { exit(1); break; } case (private_chat): //私聊 { deal_private(client_addr); break; } case(group_chat): //群聊 { deal_group(client_addr); break; } case(online): //查看在线人数 { deal_online(client_addr); break; } case (like): //点赞 { deal_like(client_addr); break; } case(expression): //群发表情 { deal_expression(client_addr); break; } case(phrases): //发送常用语 { deal_phrases(client_addr); break; } case(Vip): //开通会员 { deal_vip(client_addr); break; } case(Shutup): //禁言 { deal_shutup(client_addr); break; } case(kick): //踢人 { deal_kick(client_addr); break; } case (file_transfer): //文件传输 { deal_ftp(client_addr); break; } case(Exit): //下线 { printf("NAME : %s\n", RecvBuf.username); deal_quit(client_addr); break; } } } sqlite3_close(ppdb); return 0; }
/*************************************************** File name: UDP_client.c Author:華仔 Data:2017.12.25 Description:聊天软客户端 ***************************************************/ #include "UDP_chatroom.h" #define PORT 8888 typedef struct info { char username[20]; //用户名 char account[20]; //账号 char passwd[20]; //密码 char from_name[20]; //发信人 char to_name[20]; //收信人 char moto[30]; //个性签名 char online_name[20][20]; //在线人名 int online_num; //在线人数 int cmd; //提取操作符 int vip; //会员标志 int likes; //点赞数 int result; //返回操作结果 char msg[1024]; //发送、接收消息 char e_s; //确认发送的表情 char p_s; //确认发送的常用语 char file_name[50]; //文件名 char Ftp[2048]; //文件传输 }Info; struct sockaddr_in server_addr; Info SendBuf; Info RecvBuf; sqlite3 *ppdb = NULL; //数据库 int sockfd; int State; int LIKES; //点赞标志 int OUT = 0; //踢人标志 char Name[20]; int ret; /****************************************************************/ //时间函数 void time_show() { time_t rawtime; struct tm *timeinfo; time (&rawtime); timeinfo = localtime(&rawtime); printf("Time: %d 年 %d 月 %d 日 %d 时 %d 分 %d 秒\n\n", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); } //防止空格影响 void SCAN_N() { char ch; while((getchar()) != '\n' && ch != EOF); } //欢迎界面 void Welcome(void) { system("clear"); printf("\t\t\t\t*********************************************\n"); printf("\t\t\t\t**************欢迎来到華仔聊天室*************\n"); printf("\t\t\t\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 欢 迎 使 用 程 序 猿 APP |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); sleep(2); } //退出界面 void Bye(void) { system("clear"); printf("\t\t\t\t*********************************************\n"); printf("\t\t\t\t**************深情告别華仔聊天室*************\n"); printf("\t\t\t\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n"); printf("\t\t\t\t| See you lala. |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); sleep(1); system("clear"); printf("\t\t\t\t*********************************************\n"); printf("\t\t\t\t**************深情告别華仔聊天室*************\n"); printf("\t\t\t\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n"); printf("\t\t\t\t| See you lala.. |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); sleep(1); system("clear"); printf("\t\t\t\t*********************************************\n"); printf("\t\t\t\t**************深情告别華仔聊天室*************\n"); printf("\t\t\t\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n"); printf("\t\t\t\t| See you lala... |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); sleep(2); } //主界面 void Display() { system("clear"); printf("\t\t\t\t*********************************************\n"); printf("\t\t\t\t**************欢迎来到華仔聊天室*************\n"); printf("\t\t\t\t|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|\n"); printf("\t\t\t\t| 1.注册(REG) |\n"); printf("\t\t\t\t| 2.登入(LOG) |\n"); printf("\t\t\t\t| 3.退出(EXIT) |\n"); printf("\t\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); printf("\t\t\t\t******************* 请 选 择 ****************\n"); } //注册界面 void RegFace() { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 正 在 注 册 . |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 稍 后 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 正 在 注 册 . . |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 稍 后 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 正 在 注 册 . . . |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 稍 后 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 恭 喜 你 : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 注 册 成 功 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(2); } //登入界面 void LogFace() { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请稍等! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登入中. |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请稍等! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登入中.. |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请稍等! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登入中... |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请稍等! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登入中. |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请稍等! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登入中.. |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(1); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请稍等! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登入中... |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(2); system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 恭 喜 你 : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 登 入 成 功 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(2); } // 登入后的界面 void InterFace() { system("clear"); printf("\t\t\t\t"); time_show(); if(RecvBuf.vip == 1) { printf("\t\t\t\t _____________________________________________ \n"); printf("\t\t\t\t|**尊 贵 VIP 用 户:%s \n", Name); printf("\t\t\t\t|******个 性 签 名:%s \n", RecvBuf.moto); printf("\t\t\t\t|******收 到 的 赞:%d \n", LIKES); printf("\t\t\t\t|_____________________________________________ \n"); printf("\t\t\t\t|*********************************************|\n"); printf("\t\t\t\t|***********Welcome HUAZAI Chatroom***********|\n"); printf("\t\t\t\t|*********************************************|\n"); printf("\t\t\t\t| 1. 私聊 |\n"); printf("\t\t\t\t| 2. 群聊 |\n"); printf("\t\t\t\t| 3. 查看在线人数 |\n"); printf("\t\t\t\t| 4. 点赞 |\n"); printf("\t\t\t\t| 5. 更改个性签名 |\n"); printf("\t\t\t\t| 6. 文件传输 |\n"); printf("\t\t\t\t| 7. 群发表情 |\n"); printf("\t\t\t\t| 8. 私发常用语 |\n"); printf("\t\t\t\t| 9. 查看聊天记录 |\n"); printf("\t\t\t\t| 10. 注册会员 |\n"); printf("\t\t\t\t| 11. 踢人(需开通会员) |\n"); printf("\t\t\t\t| 12. 禁言(需开通会员) |\n"); printf("\t\t\t\t| 13. 解禁(需开通会员) |\n"); printf("\t\t\t\t| 14. 下线 |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|___________________________________華仔工作室|\n"); printf("\t\t\t\t************* 请 做 出 你 的 选 择 ************\n"); } else { printf("\t\t\t\t _____________________________________________ \n"); printf("\t\t\t\t|普 通 用 户:%s \n",Name); printf("\t\t\t\t|个 性 签 名:%s \n", RecvBuf.moto); printf("\t\t\t\t|收 到 的 赞:%d \n", LIKES); printf("\t\t\t\t|_____________________________________________ \n"); printf("\t\t\t\t|*********************************************|\n"); printf("\t\t\t\t|***********Welcome HUAZAI Chatroom***********|\n"); printf("\t\t\t\t|*********************************************|\n"); printf("\t\t\t\t| 1. 私聊 |\n"); printf("\t\t\t\t| 2. 群聊 |\n"); printf("\t\t\t\t| 3. 查看在线人数 |\n"); printf("\t\t\t\t| 4. 点赞 |\n"); printf("\t\t\t\t| 5. 更改个性签名 |\n"); printf("\t\t\t\t| 6. 文件传输 |\n"); printf("\t\t\t\t| 7. 群发表情 |\n"); printf("\t\t\t\t| 8. 私发常用语 |\n"); printf("\t\t\t\t| 9. 查看聊天记录 |\n"); printf("\t\t\t\t| 10. 注册会员 |\n"); printf("\t\t\t\t| 11. 踢人(需开通会员) |\n"); printf("\t\t\t\t| 12. 禁言(需开通会员) |\n"); printf("\t\t\t\t| 13. 解禁(需开通会员) |\n"); printf("\t\t\t\t| 14. 下线 |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|___________________________________華仔工作室|\n"); printf("\t\t\t\t************* 请 做 出 你 的 选 择 ************\n"); } } //注册 int RegAcc() { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| _________________________ |\n"); printf("\t\t\t\t| 用户名|________________________| |\n"); printf("\t\t\t\t| _________________________ |\n"); printf("\t\t\t\t| 账号|________________________| |\n"); printf("\t\t\t\t| _________________________ |\n"); printf("\t\t\t\t| 密码|________________________| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n\n"); SendBuf.cmd = REG; SendBuf.vip = 0; SendBuf.likes = 0; strcpy(SendBuf.moto, "helloworld"); char psd1[20] = {0}; char psd2[20] = {0}; printf("\n\n"); printf("\t\t\t\t请输入用户名:\n"); printf("\t\t\t\t"); scanf("\t\t\t\t%s", SendBuf.username); SCAN_N(); printf("\t\t\t\t请输入账号:\n"); printf("\t\t\t\t"); scanf("\t\t\t\t%s", SendBuf.account); SCAN_N(); printf("\t\t\t\t请输入密码:\n"); printf("\t\t\t\t"); scanf("\t\t\t\t%s", psd1); SCAN_N(); printf("\t\t\t\t请确认密码:\n"); printf("\t\t\t\t"); scanf("\t\t\t\t%s", psd2); SCAN_N(); if(strcmp(psd1, psd2) != 0) { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 两次输入密码不一致, |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 重 新 输 入 密 码 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(2); scanf("%s",psd2); } else { strcpy(SendBuf.passwd, psd1); } } //登入 int Login() { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入華仔聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| _________________________ |\n"); printf("\t\t\t\t| 账号|________________________| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| _________________________ |\n"); printf("\t\t\t\t| 密码|________________________| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n\n"); SendBuf.cmd = LOG; printf("\n\n"); printf("\t\t\t\t请输入账号:\n"); printf("\t\t\t\t"); scanf("%s", SendBuf.account); SCAN_N(); printf("\t\t\t\t请输入密码:\n"); printf("\t\t\t\t"); scanf("%s", SendBuf.passwd); SCAN_N(); } //接收服务器反馈 void *Recv_from_server(void *arg) { int i; int length = sizeof(server_addr); while(1) { ret = recvfrom(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0, (struct sockaddr *)&server_addr, &length); if (ret < 0) { perror("recvfrom"); exit(1); } switch(RecvBuf.result) { case(private_chat): { printf("\n\t\t\t\t好友%s 给你发了一条消息:%s\n",RecvBuf.from_name,RecvBuf.msg); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(group_chat): { printf("\n\t\t\t\t%s 群发了一条消息:%s\n",RecvBuf.from_name,RecvBuf.msg); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(SEND_SUCCESS): { sleep(1); printf("\n\n\n\n"); printf("\t\t\t\t发送成功\n"); sleep(1); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(SEND_FAILED): { sleep(2); printf("\n\n\n\n"); printf("\t\t\t\t操 作 失 败 了...\n"); sleep(3); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(online): { system("clear"); printf("\n\n\t\t\t\t当前在线好友人数: %d\n",RecvBuf.online_num); for(i = 0 ; i < RecvBuf.online_num ; i++) { printf("\n\t\t\t\t%s\n",RecvBuf.online_name[i]); } memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(like): { LIKES = RecvBuf.likes; printf("\n\t\t\t\t好友%s 给你点了个赞!\n", RecvBuf.from_name); sleep(1.5); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(LIKE_SUCCESS): { sleep(1); printf("\n\n\n\n"); printf("\t\t\t\t点赞成功!\n"); sleep(1); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(VIP_SUCCESS): { sleep(1); printf("\n\n\n"); printf("\t\t\t\t恭喜你,开通会员成功!\n"); sleep(1); memset(&RecvBuf.result,0,sizeof(RecvBuf.result)); break; } case(Shutup): { State = Shutup; printf("\t\t\t\t%s已经把您禁言了!\n",RecvBuf.from_name); sleep(2.5); break; } case(SHUTUP_SUCCESS): { sleep(1); printf("\n\n\t\t\t\t禁言成功!\n"); sleep(2); break; } case(kick): { OUT = 1; printf("\n\n\t\t\t\t您已经被%s踢出了聊天室,请重新登录!\n",RecvBuf.from_name); sleep(1); // exit(1); return (void *)ERROR; break; } case(KICK_SUCCESS): { sleep(1); printf("\n\n\t\t\t\t恭喜您!对方已成功被踢下线!\n"); sleep(3); break; } case(expression): { char er[20]; switch (RecvBuf.e_s) { case '1' : { strcpy(er, ":-D"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '2' : { strcpy(er, "= =#"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '3' : { strcpy(er, "*\(^_^)/*"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '4' : { strcpy(er, "╮( ̄▽  ̄)╭"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '5' : { strcpy(er, "づ ̄ 3 ̄)づ"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '6' : { strcpy(er, "(T_T)"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '7' : { strcpy(er, "b( ̄▽ ̄)d"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '8' : { strcpy(er, "(︶︿︶)"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } case '9' : { strcpy(er, ">3<"); printf("\t\t\t\t%s群发了一个表情:%s\n", RecvBuf.from_name, er); break; } default : { system("clear"); printf("\n\n\n\n\t\t\t\t对不起,没有这种操作!/n"); break; } } break; } case(phrases): { char ph[60]; switch (RecvBuf.p_s) { case '1' : { strcpy(ph, " I promise 我保证."); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '2' : { strcpy(ph, "Take care 保重!"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '3' : { strcpy(ph, "Be careful! 注意!"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '4' : { strcpy(ph, "Cheer up! 振作起来!"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '5' : { strcpy(ph, "I doubt it 我怀疑"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '6' : { strcpy(ph, "Bless you! 祝福你!"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '7' : { strcpy(ph, "Keep it up! 坚持下去!"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '8' : { strcpy(ph, "I'm single. 我是单身贵族"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } case '9' : { strcpy(ph, "That's all! 就这样!"); printf("\t\t\t\t%s给您发送了一句话:%s\n", RecvBuf.from_name, ph); break; } default : { system("clear"); printf("\n\n\n\n\t\t\t\t对不起,没有这种操作!\n"); break; } } break; } } } } //处理登陆后的函数 int after_login() { if(OUT == 1) { OUT--; return Exit; } int fd; int choice; char MSG[2048] = {0}; char filename[100] ={0}; while(1) { InterFace(); scanf("%d",&choice); switch(choice) { case 1: //私聊 { system("clear"); if(State == Shutup) { printf("\n\t\t\t\t对不起,您已经被禁言了!\n"); sleep(2); break; } printf("\n\n"); printf("\t\t\t\t请输入私聊对象:\n"); printf("\t\t\t\t"); scanf("%s", SendBuf.to_name); SCAN_N(); printf("\t\t\t\t请输入要发送的消息:\n"); printf("\t\t\t\t"); scanf("%s", SendBuf.msg); SCAN_N(); SendBuf.cmd = private_chat; strcpy(SendBuf.username,Name); if(strcmp(SendBuf.to_name, Name) ==0) { sleep(1); system("clear"); printf("\t\t\t\t不可以给自己发信息!\n"); sleep(2); break; } ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_pchat"); exit(1); } sprintf(filename, "%s chat with %s.txt", Name, SendBuf.to_name); fd = open(filename, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR); if(fd == -1) { perror("open"); exit(1); } sprintf(MSG, "%s 给 %s 发送了一条消息:%s", Name, SendBuf.to_name, SendBuf.msg); ret = write(fd, MSG, strlen(MSG)); if(ret == -1) { perror("write"); exit(1); } printf("\n\n\t\t\t\t正在发送,请稍后...\n"); sleep(2); break; } case 2: //群聊 { system("clear"); if(State == Shutup) { printf("\n\n\t\t\t\t不好意思,您已经被禁言了!\n"); sleep(2); break; } printf("\n\n\t\t\t\t请输入消息:\n"); printf("\t\t\t\t"); scanf("%s", SendBuf.msg); SendBuf.cmd = group_chat; strcpy(SendBuf.username,Name); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_groupchat"); exit(1); } printf("\n\n\t\t\t\t正在发送,请稍后...\n"); sleep(2); break; } case 3: //查看在线人数 { system("clear"); SendBuf.cmd = online; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_onlinenum"); exit(1); } sleep(3.5); break; } case 4: //点赞 { system("clear"); SendBuf.cmd = like; printf("\n\n\n\t\t\t\t你想给谁点赞:"); scanf("%s", SendBuf.to_name); SCAN_N(); strcpy(SendBuf.username, Name); if(strcmp(Name, SendBuf.to_name) == 0) { sleep(1); printf("\n\n\n\t\t\t\t不可以给自己点赞!\n"); sleep(2); break; } ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr,sizeof(server_addr)); if (ret < 0) { perror("sendto_onlinenum"); exit(1); } printf("\n\n\t\t\t\t请稍后...\n"); sleep(2); break; } case 5: //修改个签 { SendBuf.cmd = motto_change; printf("\n\n\n\n\t\t\t\t请更改:\n\n\t\t\t\t"); scanf("%s", SendBuf.moto); SCAN_N(); strcpy(SendBuf.username, Name); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr,sizeof(server_addr)); if (ret < 0) { perror("sendto_motto_change"); exit(1); } printf("\n\n\t\t\t\t请稍等...\n"); sleep(2); break; } case 6: //文件传输 { int ret; FILE *fp; printf("\n\n\t\t\t\t接收方用户名:\n"); printf("\n\t\t\t\t"); scanf("%s", SendBuf.to_name); SCAN_N(); if (!strcmp(SendBuf.to_name, Name)) { printf("不可以发文件给自己!\n"); sleep(1); break; } strcpy(SendBuf.username, Name); printf("\n\n\t\t\t\t请选择文件:\n"); printf("\n\t\t\t\t"); scanf("%s", SendBuf.file_name); SendBuf.cmd = file_transfer; fp = fopen(SendBuf.file_name, "r"); if (NULL == fp) { printf("\n\t\t\t\t无法打开,该文件不存在!\n"); sleep(2); break; } ret = fread(SendBuf.Ftp, 1, sizeof(SendBuf.Ftp), fp); if (0 == ret) { perror("fread_file_transfer"); exit(1); } fclose(fp); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_file"); return; } sleep(2); } case 7: //发送表情(群发) { system("clear"); if(State == Shutup) { printf("\n\n\t\t\t\t您处于被禁言状态!无法发言!开通会员可以解禁\n"); sleep(2); break; } char e[10]={0}; //输入表情选项 SendBuf.cmd = expression; printf("\n\n\n\n\t\t\t\t"); printf("***************请选择以下的表情**************\n\n"); printf("\t\t\t\t1 开心 :-D\n"); printf("\t\t\t\t2 生气 = =#\n"); printf("\t\t\t\t3 为你加油 *\(^_^)/*\n"); printf("\t\t\t\t4 两手一摊 ╮( ̄▽  ̄)╭\n"); printf("\t\t\t\t5 飞吻 づ ̄ 3 ̄)づ\n"); printf("\t\t\t\t6 哭泣 (T_T)\n"); printf("\t\t\t\t7 竖起大拇指 b( ̄▽ ̄)d\n"); printf("\t\t\t\t8 不满 (︶︿︶)\n"); printf("\t\t\t\t9 亲亲 >3<\n\n"); scanf("%s", e); SCAN_N(); SendBuf.e_s = e[0]; strcpy(SendBuf.username,Name); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_expression"); exit(1); } printf("\n\n\t\t\t\t发送中...\n"); sleep(2); break; } case 8: //发送常用语(私发) { if(State == Shutup) { printf("\n\n\t\t\t\t您处于被禁言状态!无法发言!开通会员可以解禁\n"); sleep(2); break; } char p[10]; //输入常用语选项 printf("\n\n\t\t\t\t请输入对方的名字:\n\n"); printf("\t\t\t\t"); scanf("%s", SendBuf.to_name); strcpy(SendBuf.username,Name); if(!strcmp(Name,SendBuf.to_name)) { sleep(1); system("clear"); printf("\n\n\t\t\t\t不可以给自己发送常用语!\n\n"); sleep(3); break; } SendBuf.cmd = phrases; printf("\n\n\n\n\t\t\t\t"); printf("***************请选择以下的常用语**************\n\n"); printf("\t\t\t\t1 I promise 我保证.\n"); printf("\t\t\t\t2 Take care 保重!\n"); printf("\t\t\t\t3 Be careful! 注意!\n"); printf("\t\t\t\t4 Cheer up! 振作起来!\n"); printf("\t\t\t\t5 I doubt it 我怀疑\n"); printf("\t\t\t\t6 Bless you! 祝福你!\n"); printf("\t\t\t\t7 Keep it up! 坚持下去!\n"); printf("\t\t\t\t8 I'm single. 我是单身贵族\n"); printf("\t\t\t\t9 That's all! 就这样!\n"); scanf("%s", p); SCAN_N(); SendBuf.p_s = p[0]; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_expression"); exit(1); } printf("\n\t\t\t\t正在发送...\n"); sleep(2); break; } case 9: //查看聊天记录 { system("clear"); char b[20]; char file_name[50]; char File[2048]; char kl; int fd1; int i = 0; printf("\n\n\n\n\t\t\t\t您想看和谁的聊天记录:\n"); printf("\n\t\t\t\t"); scanf("%s",b); SCAN_N(); sprintf(file_name, "%s chat with %s.txt", Name, b); fd1 = open(file_name,O_RDONLY,S_IRUSR | S_IWUSR); if(fd1 == -1) { system("clear"); printf("\n\n\n\n\n\n\n\t\t\t\t您与%s还没有聊天记录!\n",b); sleep(2); break; } while(1) { memset(&kl, 0, sizeof(kl)); ssize_t read_bytes = read(fd1, &kl, sizeof(kl)); if(read_bytes == -1) { perror("read"); return -1; } if(read_bytes == 0) { break; } File[i] = kl; i++; } File[i] = '\0'; printf("\n\t\t\t\t%s\n", File); sleep (4); break; } case 10: //开通会员 { system("clear"); if(SendBuf.vip == 0) { char a[2]; system("clear"); printf("\n\n\n\t\t您好,请先支付200元,就能永久享受vip权限了!\n"); printf("\n\t\t\t\t确认支付?(y/n)\n"); printf("\n\t\t\t\t"); scanf("%s",a); if(a[0] == 'y') { strcpy(SendBuf.username,Name); SendBuf.vip = 1; SendBuf.cmd = Vip; ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_vip"); exit(1); } printf("\n\n\t\t\t\t请稍等...\n"); sleep(2); } else if(a[0] == 'n') { break; } else { printf("\n\n\t\t输入错误!\n\n"); sleep(2); } } else if(SendBuf.vip == 1) { printf("\n\n\n\n\n\n\t\t\t您已经是尊贵的VIP会员了!\n"); sleep(2); } break; } case 11: //踢人 { if(SendBuf.vip == 1) { system("clear"); printf("\n\n\t\t\t\t请输入您想踢的人:\n"); printf("\n\t\t\t\t"); scanf("%s",SendBuf.to_name); SendBuf.cmd = kick; strcpy(SendBuf.username, Name); if(strcmp(SendBuf.to_name, Name) ==0) { printf("\n\t\t\t\t不可以踢自己!\n"); sleep(2); break; } ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_kick1"); exit(1); } printf("\n\n\t\t\t\t请稍等...\n"); sleep(2); } else if(SendBuf.vip == 0) { printf("\n\n\t\t\t\t您还不是VIP会员,无法踢人!"); sleep(2); } break; } case 12: //禁言 { if(SendBuf.vip == 1) { system("clear"); printf("\n\n\n\n\t\t\t\t请输入您想要禁言的人:\n"); printf("\n\t\t\t\t"); scanf("%s",SendBuf.to_name); SendBuf.cmd = Shutup; strcpy(SendBuf.username,Name); if(strcmp(SendBuf.to_name, Name) ==0) { sleep(1); system("clear"); printf("\n\n\n\n\t\t\t\t不可以禁言自己!\n"); sleep(2); break; } ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_shutup"); exit(1); } printf("\n\t\t\t\t请稍等...\n"); sleep(2); } else if(SendBuf.vip == 0) { printf("您还不是VIP会员,无法禁言 !\n"); sleep(2); } break; } case 13: //解禁 { char x[2]; if(State == 0) { system("clear"); printf("\n\n\n\t\t\t\t您没有被禁言, 无需解禁!\n"); sleep(2); } else if(State == Shutup) { if(SendBuf.vip == 0) { system("clear"); printf("\n\n\n\n\t\t\t\t您还没有开通会员,解禁请先开通会员!\n"); sleep(2); } else if(SendBuf.vip == 1) { system("clear"); printf("\n\n\n\n\t\t\t\t您想现在解禁吗!(y/n)\n"); scanf("%s",x); SCAN_N(); if(x[0] == 'y') { State = 0; system("clear"); printf("\n\n\n\t\t\t\t恭喜您成功解禁!\n"); sleep(2); } } } break; } case 14: //下线 { SendBuf.cmd = Exit; strcpy(SendBuf.username,Name); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_quit"); exit(1); } sleep(0.5); return Exit; } default: { system("clear"); printf("\n\n\n\n"); printf("\n\n\t\t客官,手抖了!请重新输入\n"); sleep(1.5); break; } } } } int main() { int choice; int length = sizeof(server_addr); pthread_t tid; sockfd = socket(PF_INET, SOCK_DGRAM, 0); if (-1 == sockfd) { perror("sockt"); exit(1); } bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = PF_INET; server_addr.sin_port = PORT; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); Welcome(); while(1) { Display(); scanf("%d",&choice); switch(choice) { case 1: //注册 { RegAcc(); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_register"); exit(1); } bzero(&SendBuf, sizeof(SendBuf)); ret = recvfrom(sockfd, &RecvBuf, sizeof(RecvBuf), 0, (struct sockaddr *)&server_addr, &length); if (ret < 0) { perror("recvfrom_register"); exit(1); } if(RecvBuf.result == REG_SUCCESS) { RegFace(); } else if(RecvBuf.result == EXISTING_ACC) { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎注册COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 对 不 起, |\n"); printf("\t\t\t\t| 该 账 号 已 被 注 册 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 重 新 注 册 账 号 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n\n"); sleep(1); } sleep(2); break; } case 2: //登录 { Login(); ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { perror("sendto_Login"); exit(1); } bzero(&SendBuf, sizeof(SendBuf)); ret = recvfrom(sockfd, &RecvBuf, sizeof(RecvBuf), 0, (struct sockaddr *)&server_addr, &length); if (ret < 0) { perror("recvfrom_login"); exit(1); } strcpy(Name,RecvBuf.username); if(RecvBuf.result == LOG_SUCCESS) { LIKES = RecvBuf.likes; LogFace(); ret = pthread_create(&tid, NULL, (void *)Recv_from_server, (void *)&sockfd); if (ret < 0) { perror("pthread_create"); exit(1); } pthread_detach(tid); ret = after_login(); if(ret == Exit) { break; } } else if(RecvBuf.result == LOGGED_ACC) { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 对 不 起 , |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 该 账 号 已 登 入 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 重 新 登 入 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(2); } else if(RecvBuf.result == ERROR) { system("clear"); printf("\t\t\t\t _________________________________________ \n"); printf("\t\t\t\t| Time : |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| 欢迎登入COCO聊天室 |\n"); printf("\t\t\t\t|*****************************************|\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 对 不 起 , |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 您 输 入 的 账 号 或 密 码 不 正 确 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 请 重 新 登 入 ! |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| |\n"); printf("\t\t\t\t| 華仔工作室 |\n"); printf("\t\t\t\t|_________________________________________|\n"); sleep(2); } break; } case 3: //退出 { Bye(); system("clear"); exit(1); break; } default : { system("clear"); printf("\n\n\n\n"); printf("\n\n\t\t客官,手抖了!请重新输入...\n"); sleep(2); break; } } } return 0; }
相关文章推荐
- Linux聊天室项目 -- ChatRome(select实现)
- 自写聊天室_LinuxC实现(4)——项目文档
- 基于Linux的消息队列及多线程编程实现的聊天室(一)
- 【Jenkins教程二】基于Linux实现Jenkins+maven+tomcat的自动化构建部署项目
- 基于Linux C 用socket和线程 实现的简易聊天室之客户端
- linux下SVN配置实现项目目录自动更新以及源码安装的操作方法
- 基于linux的TCP网络聊天室设计与实现
- Linux学习之web服务器(1)--基于源码实现SSL的安全连接
- 【Jenkins教程三】基于Linux实现Jenkins+maven+git+tomcat的自动化构建部署项目
- 基于Linux的消息队列及多线程编程实现的聊天室(一)
- 【Jenkins教程三】基于Linux实现Jenkins+maven+git+tomcat的自动化构建部署项目
- 【Jenkins教程二】基于Linux实现Jenkins+maven+tomcat的自动化构建部署项目
- linux下SVN配置实现项目目录自动更新以及源码安装
- 嵌入式实战项目:基于嵌入式linux花卉大棚温湿度监测与调节系统的设计与实现
- 网络编程项目:linux下基于C/S架构的聊天室
- 自写聊天室_LinuxC实现(1)——项目部署遇到问题及解决方法
- 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。
- 基于Linux的消息队列及多线程编程实现的聊天室(二)代码分析
- Java基于UDP协议实现简单的聊天室程序
- 第十三章 网络命名空间(内核源码实现)--基于Linux3.10