1、UDP_chatroom.h
/***************************************************
File name: UDP_chatroom.h
Author:刘磊
Data:2021.1.23
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 //更改个性签名成功
#define RECVFILE_SUCCESS 33 //接受文件成功
#define SENDFILE_SUCCESS 34 //发送文件成功
/***************************************************************/
#endif
2、UDP_server.c
/*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[200] = {0};
char *errmsg = NULL;
sprintf(sql, "insert into chatroom(username, account, passwd, likes, vip, moto) values('%s','%s','%s','%d','%d', '%s')",RecvBuf.username, RecvBuf.account, RecvBuf.passwd, RecvBuf.likes, RecvBuf.vip, RecvBuf.moto);
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[200] = {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);
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_moto_change(struct sockaddr_in temp_addr)
{
char *errmsg = NULL;
char **Result = NULL;
int nRow;
int nColumn;
char sql[100];
sprintf(sql, "update chatroom set moto = '%s' where username = '%s'", RecvBuf.moto, RecvBuf.username);
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.username) == 0)
{
sprintf(sql, "select moto from chatroom where username = '%s'", RecvBuf.username);
ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, &errmsg);
if(ret != SQLITE_OK)
{
printf("select fail:%d(%s)\n", ret, errmsg);
return -1;
}
strcpy(SendBuf.moto, Result[1]);
SendBuf.result = motto_change;
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_moto");
}
break;
}
tmp = tmp->next;
}
SendBuf.result = CHANGE_SUCCESS;
ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
if(ret == -1)
{
perror("sendto_moto_succuess");
}
}
//发送表情(群发)
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 成为管理\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.to_name,RecvBuf.to_name);
strcpy(SendBuf.file_name, RecvBuf.file_name);//拷贝文件名
strcpy(SendBuf.Ftp, RecvBuf.Ftp);//拷贝文件内容
SendBuf.result = RECVFILE_SUCCESS;
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 = SENDFILE_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;
//SendBuf.vip = RecvBuf.vip;
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;
}
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;
//SendBuf.vip = RecvBuf.vip;
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;
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 (motto_change): //修改个性签名
{
deal_moto_change(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;
}
3、UDP_client.c
/***************************************************
File name: UDP_client.c
Author:刘磊
Data:2021.1.23
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; //踢人标志
int VIP;
char Name[20];
int MiMa;
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");
}
//主界面
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| 欢迎注册 聊天室 |\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(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|******管 理 员:%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 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 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| 欢迎注册 聊天室 |\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);
char *errmsg = NULL;
char **Result = NULL;
int nRow;
int nColumn;
char sql[300];
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));
/* if(State == Shutup)
{
printf("419\n");
sprintf(sql, "select vip from chatroom where username = '%s'", RecvBuf.from_name);
printf("421\n");
ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, &errmsg);
if(ret != SQLITE_OK)
{
printf("select fail:%d(%s)\n", ret, errmsg);
exit(1);
}
printf("426\n");
if(1 == *(Result[1]) - 48)
{
MiMa = 1;
}
}*/
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(SENDFILE_SUCCESS):
{
sleep(1);
printf("\n\n\n\n");
printf("\t\t\t\t文件发送成功\n");
sleep(3);
memset(&RecvBuf.result,0,sizeof(RecvBuf.result));
break;
}
case(RECVFILE_SUCCESS):
{
if(strcmp(Name,RecvBuf.to_name) == 0)
{
sleep(1);
printf("\n\n\n\n");
printf("\t\t\t\t好友%s给你发送了一个文件%s\n",RecvBuf.from_name,RecvBuf.file_name);
printf("\t\t\t\t文件内容如下:\n");
printf("\t\t\t\t%s\n",RecvBuf.Ftp);
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(CHANGE_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(1);
break;
}
case(SHUTUP_SUCCESS):
{
sleep(1);
printf("\n\n\t\t\t\t禁言成功!\n");
sleep(1);
break;
}
case(kick):
{
OUT = 1;
printf("\n\n\t\t\t\t您已经被%s踢出了聊天室,请重新登录!\n",RecvBuf.from_name);
sleep(1);
return (void *)ERROR;
break;
}
case(KICK_SUCCESS):
{
sleep(1);
printf("\n\n\t\t\t\t恭喜您!对方已成功被踢下线!\n");
sleep(1);
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 mima[10];
char filename1[100] ={0};
char filename2[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(1);
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(filename1, "%s_chat_with_%s.txt", Name, SendBuf.to_name);
fd = open(filename1, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
if(fd == -1)
{
perror("open");
exit(1);
}
sprintf(filename2, "%s_chat_with_%s.txt", SendBuf.to_name, Name);
fd = open(filename2, 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(1);
break;
}
case 2: //群聊
{
system("clear");
if(State == Shutup)
{
printf("\n\n\t\t\t\t不好意思,您已经被禁言了!\n");
sleep(1);
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(1);
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);
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(1);
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(1);
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(1);
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(1);
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(1);
break;
}
case 7: //发送表情(群发)
{
system("clear");
if(State == Shutup)
{
printf("\n\n\t\t\t\t您处于被禁言状态!无法发言!开通会员可以解禁\n");
sleep(1);
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(1);
break;
}
case 8: //发送常用语(私发)
{
if(State == Shutup)
{
printf("\n\n\t\t\t\t您处于被禁言状态!无法发言!开通会员可以解禁\n");
sleep(1);
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(1);
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(1);
break;
}
case 9: //查看聊天记录
{
system("clear");
char b[20];
char file_name[50];
char File[2048];
char kl;
FILE *fp;
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);
fp = fopen(file_name,"r");
if(fp == NULL)
{
system("clear");
printf("\n\n\n\n\n\n\n\t\t\t\t您与%s还没有聊天记录!\n",b);
sleep(1);
break;
}
ret = fread(File, 10, sizeof(File), fp);
if (0 == ret)
{
perror("fread_file_failure");
exit(1);
}
fclose(fp);
printf("\n\t\t\t\t和%s聊天内容如下:",b);
printf("\n\t\t\t\t%s\n", File);
sleep (3);
break;
}
case 10: //成为管理
{
system("clear");
if(SendBuf.vip == 0)
{
char a[2];
system("clear");
printf("\n\n\n\t\t您好,请输入管理密码:\n");
scanf("%s", mima);
if(strcmp(mima, "123456") == 0)
a[0] = 'y';
else
a[0] = 'n';
printf("\n\t\t\t\t");
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(1);
}
else if(a[0] == 'n')
{
break;
}
else
{
printf("\n\n\t\t输入错误!\n\n");
sleep(1);
}
}
else if(SendBuf.vip == 1)
{
printf("\n\n\n\n\n\n\t\t\t您已经是管理员了!\n");
sleep(1);
}
break;
}
case 11: //踢人
{
if(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(1);
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(1);
}
else if(SendBuf.vip == 0)
{
printf("\n\n\t\t\t\t您还不是管理员,无法踢人!");
sleep(1);
}
break;
}
case 12: //禁言
{
if(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(1);
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(1);
}
else if(SendBuf.vip == 0)
{
printf("您还不是管理员,无法禁言 !\n");
sleep(1);
}
break;
}
case 13: //解禁
{
char x[10];
if(State == 0)
{
system("clear");
printf("\n\n\n\t\t\t\t您没有被禁言, 无需解禁!\n");
sleep(1);
}
else if(State == Shutup)
{
if(SendBuf.vip == 0)
{
system("clear");
printf("\n\n\n\n\t\t\t\t您还不是管理员,不能解禁!");
sleep(2);
}
else if(SendBuf.vip == 1)
{
system("clear");
printf("\n\n\n\n\t\t\t\t您现在解禁么?(y/n)");
scanf("%s",x);
SCAN_N();
if(x[0] == 'y')
{
State = 0;
system("clear");
printf("\n\n\n\n\t\t\t\t恭喜您解禁成功!\n");
sleep(2);
}
}
/* if(MiMa == 0)
{
system("clear");
printf("\n\n\n\n\t\t\t\t!等待管理员发送解禁密码!\n");
sleep(1);
}
else if(MiMa == 1)
{
system("clear");
printf("\n\n\n\n\t\t\t\t请输入解禁密码:\n");
scanf("%s",x);
SCAN_N();
if(strcmp(x, RecvBuf.msg) == 0)
{
State = 0;
system("clear");
printf("\n\n\n\t\t\t\t恭喜您成功解禁!\n");
sleep(1);
MiMa = 0;
}
} */
}
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);
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();
//time_show();
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| 欢迎注册 聊天室 |\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(1);
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);
VIP = RecvBuf.vip;
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| 欢迎登入 聊天室 |\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);
}
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| 欢迎登入 聊天室 |\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);
}
break;
}
case 3: //退出
{
Bye();
system("clear");
exit(1);
break;
}
default :
{
system("clear");
printf("\n\n\n\n");
printf("\n\n\t\t客官,手抖了!请重新输入...\n");
sleep(1);
break;
}
}
}
return 0;
}
结果图: