客户端:
ChatRoom.h
#ifndef _CHATROOM_H_H
#define _CHATROOM_H_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sqlite3.h>
#include <pthread.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#define TRUE 1
#define FALSE 2
#define SUCCESS 3
#define FAILURE 4
#define PORT 8888
#define REGISTER 100
#define REG_SUCCESS 101
#define LOGIN 102
#define LOG_SUCCESS 103
#define LOG_FAILURE 104
#define OnLine 105
#define NoOnLine 106
#define Online 107
#define PrivateChat 108
#define OFFLINE 109
#define GroupChat 110
#define ChatVip 111
#define ShutUp 112
#define NoShutup 113
#define SHUTUP 114
#define IsChatVip 115
#define NoChatVip 116
#define IsGroupShutup 117
#define NoGroupShutup 118
#define Kick 119
#define KickSuccess 120
#define KickFailure 121
#define KickOk 122
#define KickNoOk 123
#define Expression 124
struct user
{
char id[20];
char password[20];
char username[20];
char toname[20];
int Tofd; //文件描述符
int cmd;
char online[20][20] ;
int n; //记录在线人数
char buf[100]; //聊天内容
int vip ;
int speak;
int find;
char ep;
};
struct linknode
{
struct user User;
struct linknode *next;
};
void Register(struct user *U);
void Login(struct user *U);
int isOnLine(struct linknode *List, struct user *User);
void ListInsert(struct linknode *list, struct user *User);
void TraverList(struct linknode*list, struct user *User);
void ChatRoom(int chatfd, struct user recvbuf, struct user USER);
void DeleteList(struct linknode *list, struct user *User);
void TraverId(struct linknode *list, struct user User, sqlite3 *db);
void TraverFriend(struct linknode *list, struct user User, sqlite3 *db);
void gettime();
void DealVip(struct user User, sqlite3 *db);
void Shut_up(struct user User, sqlite3 *db);
void DealKick(struct linknode *list, struct user User, sqlite3 *db);
char *nowtime();
void ExpressionShow();
void des_ep(struct user User);
#endif
Client.c
#include <stdio.h>
#include "ChatRoom.h"
int main()
{
int sockfd,ret;
struct sockaddr_in server_addr;
struct user User = {0};
char choice[20] = {0};
struct user RecvBuf = {0};
Show();
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
perror("socket");
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("192.168.0.128");
printf("Start Connecting...\n");
ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (-1 == ret)
{
perror("connect");
exit(1);
}
while(1)
{
PrintInfo();
scanf("%s", choice);
switch(atoi(&choice[0]))
{
case 1:
Register(&User);
ret = send(sockfd, &User, sizeof(User), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
ret = recv(sockfd, &RecvBuf, sizeof(RecvBuf), 0);
if (-1 == ret)
{
perror("recv");
exit(1);
}
if (RecvBuf.cmd == REG_SUCCESS)
{
printf("注册成功!\n");
}
break;
case 2:
Login(&User);
ret = send(sockfd, &User, sizeof(User), 0 );
if (-1 == ret)
{
perror("send");
exit(1);
}
ret = recv(sockfd, &RecvBuf, sizeof(RecvBuf), 0);
if (-1 == ret)
{
perror("recv");
exit(1);
}
if (RecvBuf.cmd == LOG_SUCCESS)
{
printf("登录成功!\n");
ChatRoom(sockfd, RecvBuf, User);
}
else if (RecvBuf.cmd == LOGIN)
{
printf("登录失败,您还未注册或密码有误!\n");
}
else if (RecvBuf.cmd == OnLine)
{
printf("帐号已经登录,请下线!\n");
}
break;
case 3:
exit(0);
default :
printf("请输入1-3之间的选择!\n");
break;
}
}
return 0;
}
#include <stdio.h>
#include "ChatRoom.h"
pthread_t tid;
void *Recv(void *arg)
{
struct user RecvBuf = {0};
int ret, i, oldtype;
int fd;
char tmp[1024] = {0};
char tmp_filename[200] = {0};
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
while(1)
{
ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);
if (-1 == ret)
{
perror("recv");
exit(1);
}
switch(RecvBuf.cmd)
{
case Online:
for (i = 0; i < RecvBuf.n; i++)
printf("%s在线\n", RecvBuf.online[i]);
printf("你的好友有%d人在线\n", RecvBuf.n);
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
case PrivateChat:
if (RecvBuf.find == NoShutup)
{
gettime();
printf("您的好友%s: %s\n", RecvBuf.username, RecvBuf.buf);
}
else if (RecvBuf.find == SHUTUP)
{
printf("对不起,大侠您已经被管理员禁言了!\n");
}
sprintf(tmp, "%s %s\n", nowtime(), RecvBuf.buf);
sprintf(tmp_filename, "%s 与 %s的聊天记录.txt", RecvBuf.toname, RecvBuf.username);
fd = open(tmp_filename, O_RDWR | O_CREAT | O_APPEND, 0777);
if (-1 == fd)
{
perror("open");
exit(1);
}
ret = write(fd, tmp, strlen(tmp));
if (-1 == ret)
{
perror("write");
exit(1);
}
close(fd);
memset(tmp, 0, sizeof(tmp));
memset(tmp_filename, 0, sizeof(tmp_filename));
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
case GroupChat:
if (RecvBuf.find == NoGroupShutup)
{
gettime();
printf("您收到来自好友%s的一个群发消息: %s \n", RecvBuf.username, RecvBuf. buf);
}
else
{
printf("对不起,大侠您不能和好友们说话了!\n");
}
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
case ChatVip:
if (RecvBuf.vip == 1)
{
printf("大侠恭喜您成为会员!\n");
}
else
{
printf("大侠您已经注册过会员了!\n");
}
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
case Kick:
if (RecvBuf.find == KickFailure)
{
printf("对不起,您还不是会员,无法踢人!\n");
}
else if (RecvBuf.find == KickSuccess)
{
printf("大侠您已经成功将他踢走!\n");
}
else if (RecvBuf.find == KickOk)
{
printf("对不起,您被管理员给强制下线了,期待下次能遇见您!\n");
exit(0);
}
else if (RecvBuf.find == KickNoOk)
{
printf("对不起,无法进行操作, 您踢的对象未上线或用户名错误!\n");
}
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
case ShutUp:
{
if (RecvBuf.find == IsChatVip)
{
printf("恭喜您已经使他闭嘴了!\n");
}
else if(RecvBuf.find == NoChatVip)
{
printf("大侠您还不是会员哦,无法进行禁言功能!\n");
}
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
}
case Expression:
{
if (RecvBuf.find == SHUTUP)
{
printf("大侠您被禁言了,无法发送表情!\n");
}
else if(RecvBuf.find == NoShutup)
{
des_ep(RecvBuf);
}
memset(&RecvBuf, 0, sizeof(RecvBuf));
break;
}
}
}
}
void Show()
{
system("clear");
printf("\t\t\t\t***********************************************************************\n\n\n\n");
printf("\t\t\t\t 欢迎您来到大侠聊天室 \n\n\n\n");
printf("\t\t\t\t************************************************************************\n\n\n\n");
sleep(2);
system("clear");
}
void PrintInfo()
{
printf("\t\t\t\t\t\t************************************************************************\n\n");
printf("\t\t\t\t\t\t 大侠聊天室 \n");
printf("\t\t\t\t\t\t 1.注册用户 2.登录用户 \n");
printf("\t\t\t\t\t\t \n");
printf("\t\t\t\t\t\t 3.退出 \n");
printf("\t\t\t\t\t\t************************************************************************\n\n");
printf("请输入您的选择\n");
}
void ChatShow()
{
printf("\t\t\t\t\t\t***********************************************************************\n\n");
printf("\t\t\t\t\t\t 大侠聊天室 \n\n\n");
printf("\t\t\t\t\t\t 1.查看在线用户 \n");
printf("\t\t\t\t\t\t 2.私聊 \n");
printf("\t\t\t\t\t\t 3.群聊 \n");
printf("\t\t\t\t\t\t 4.查看聊天记录 \n");
printf("\t\t\t\t\t\t 5.创建管理员 \n");
printf("\t\t\t\t\t\t 6.踢人 \n");
printf("\t\t\t\t\t\t 7.禁言 \n");
printf("\t\t\t\t\t\t 8.发送表情 \n");
printf("\t\t\t\t\t\t 9.下线 \n");
printf("\t\t\t\t\t\t***********************************************************************\n\n");
printf("请输入您的选择\n");
}
void ExpressionShow()
{
printf("\t\t\t\t\t\t*************************************************************************\n\n");
printf("\t\t\t\t\t\t 1 开心 (^_^) \n");
printf("\t\t\t\t\t\t 2.生气 = || = \n");
printf("\t\t\t\t\t\t 3.不屑 (-v -) \n");
printf("\t\t\t\t\t\t 4.为你加油 *\(^_^)/* \n");
printf("\t\t\t\t\t\t 5.哭泣 (T_T) \n");
printf("\t\t\t\t\t\t 6.不满 (~|~) \n");
printf("\t\t\t\t\t\t 7.竖起大拇指 b(^v^)d \n");
printf("\t\t\t\t\t\t 8.亲亲 >5< \n");
printf("\t\t\t\t\t\t*************************************************************************\n\n");
printf("请输入您想发送的表情\n");
}
void des_ep(struct user User)
{
char ex[20];
switch(User.ep)
{
case '1':
{
strcpy(ex, "(^_^)");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '2':
{
strcpy(ex, "= || =");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '3':
{
strcpy(ex, "(-v -)");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '4':
{
strcpy(ex, "*\(^_^)/*");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '5':
{
strcpy(ex, "T_T");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '6':
{
strcpy(ex,"(~|~)");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '7':
{
strcpy(ex, "b(^v^)d");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
case '8':
{
strcpy(ex, ">5<");
printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
break;
}
}
}
void gettime()
{
time_t rawtime;
struct tm * timeinfo;
time(&rawtime); //获取时间 以秒计 从1970年1月1日起算
timeinfo = localtime(&rawtime);
printf("%s", asctime(timeinfo)); //asctime() 转为标准ASCII时间格式
}
char *nowtime() //指针用于聊天记录
{
time_t rawtime;
struct tm*timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
return asctime(timeinfo);
}
void Register(struct user *U)
{
char temp[20] = {0};
U->cmd = REGISTER;
printf("开始注册!\n");
printf("请注册您的帐号:\n");
scanf("%s",U->id);
printf("请注册您的密码:\n");
scanf("%s",U->password);
strcpy(temp, U->password);
printf("请再次确认您的密码:\n");
scanf("%s",U->password);
while ((strcmp(temp, U->password)))
{
printf("输入密码出错,请重新输入正确密码:\n");
scanf("%s",U->password);
}
printf("请注册您的用户名:\n");
scanf("%s",U->username);
U->vip = 0;
U->speak = 0;
}
void Login(struct user *U)
{
U->cmd = LOGIN;
printf("请登录您的帐号!\n");
scanf("%s",U->id);
printf("请登录您的密码!\n");
scanf("%s",U->password);
}
void ChatRoom(int chatfd, struct user recvbuf, struct user USER)
{
int ret;
int fd;
char choice[20] = {0};
char pay[10] = {0};
char tmp[1024] = {0};
char tmp_filename[200] = {0};
char records[100] = {0};
char e[10] = {0};
ret = pthread_create(&tid, NULL, Recv, (void *)&chatfd); //创建线程
if (0 != ret)
{
perror("pthread_create1");
exit(1);
}
while(1)
{
ChatShow();
scanf("%s",choice);
switch(atoi(&choice[0]))
{
case 1:
USER.cmd = Online;
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
sleep(1);
/* ret = recv(chatfd,&recvbuf, sizeof(recvbuf), 0);
if (-1 == ret)
{
perror("recv");
exit(1);
}
for(i = 0; i < recvbuf.n; i++)
printf("%s 在线\n",recvbuf.online[i]); //打印在线好友用户名
printf("你的好友有%d人在线\n",recvbuf.n);*/
break;
case 2:
USER.cmd = PrivateChat;
strcpy(USER.username, recvbuf.username);
printf("大侠您想与谁说悄悄话:\n");
scanf("%s",USER.toname);
printf("大侠您想和他说什么?\n");
scanf("%s", USER.buf);
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
sprintf(tmp, "%s %s\n", nowtime(), USER.buf);
sprintf(tmp_filename, "%s 与 %s的聊天记录.txt", USER.username, USER.toname);
fd = open(tmp_filename, O_RDWR | O_CREAT | O_APPEND, 0777);
if (-1 == fd)
{
perror("open");
exit(1);
}
ret = write(fd, tmp, strlen(tmp));
if (-1 == ret)
{
perror("write");
exit(1);
}
close(fd);
memset(tmp, 0, sizeof(tmp));
memset(tmp_filename, 0, sizeof(tmp_filename));
sleep(1);
break;
case 3:
USER.cmd = GroupChat;
printf("大侠您想跟好友们说什么?\n");
scanf("%s", USER.buf);
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
sleep(1);
break;
case 4:
strcpy(USER.username, recvbuf.username);
printf("大侠您想查看与谁的聊天记录?\n");
scanf("%s", USER.toname);
sprintf(tmp_filename, "%s 与 %s的聊天记录.txt", USER.username, USER.toname);
fd = open(tmp_filename, O_RDONLY, 0777);
if (-1 == fd)
{
perror("open");
exit(1);
}
while(ret = read(fd, records, sizeof(records) - 1) != 0)
{
printf("%s", records);
memset(records, 0, sizeof(records));
}
close(fd);
break;
case 5:
USER.cmd = ChatVip;
strcpy(USER.username, recvbuf.username);
printf("大侠您想成为永久荣耀会员吗? (y/n)\n");
scanf("%s",pay);
if ('y' == pay[0])
{
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
}
sleep(2);
break;
case 6:
USER.cmd = Kick;
strcpy(USER.username, recvbuf.username);
printf("大侠您想踢走谁呢?\n");
scanf("%s", USER.toname);
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
sleep(2);
break;
case 7:
USER.cmd = ShutUp;
strcpy(USER.username, recvbuf.username);
printf("大侠您想让谁闭嘴?\n");
scanf("%s", USER.toname);
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
sleep(2);
break;
case 8:
USER.cmd = Expression;
strcpy(USER.username, recvbuf.username);
printf("大侠您想发送表情给哪位好友呢?\n");
scanf("%s", USER.toname);
ExpressionShow();
scanf("%s",e);
USER.ep = e[0];
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
sleep(1);
break;
case 9:
USER.cmd = OFFLINE;
strcpy(USER.id, recvbuf.id);
ret = send(chatfd, &USER, sizeof(USER), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
printf("下线成功,期待下次与大侠见面!\n");
sleep(1);
exit(0);
default:
printf("Unkown choice");
}
}
}