项目需求
- 使用TCP实现客户端和服务端通信
- 使用sqlite存放用户信息
- 客户端需要有登录、注册、查询单词、账号查询记录功能
- 服务器需要实时显示在线用户
解决方案
- 使用sqlite创建三个数据库,分别存放用户账号密码,单词表,用户查询记录
- 使用链表存放在线用户的信息,在子线程中循环遍历,达到实时显示在线用户的效果
主要的功能代码
头文件
#ifndef MSQLITE_H
#define MSQLITE_H
#include "Client_list.h"
typedef struct msg
{
ClistPtr C;
int cfd;
struct sockaddr_in caddr;
} Msg_t;
typedef struct umsg
{
char type;
char id[20];
char password[20];
} Umsg_t;
typedef struct Word
{
char word[20];
char mean[50];
char time[20];
} Word_t;
int Open_Dictdb(sqlite3* dictdb);
int Open_Userdb(sqlite3* userdb);
int Open_Histroy(sqlite3* histroy);
int Insert_Dict(sqlite3* dictdb);
int Connect_Event(sqlite3* userdb, sqlite3* histroy, Umsg_t usermsg, int cfd, ClistPtr C);
int User_Login(sqlite3* userdb, Umsg_t usermsg, int cfd, ClistPtr C);
int User_Register(sqlite3* userdb, Umsg_t usermsg, int cfd);
int Get_File_Line(char* file);
int Search_Word(Word_t word, int cfd, Umsg_t usermsg, sqlite3* dictdb, sqlite3* histroy);
int Show_History(sqlite3* histroy, Umsg_t usermsg, int cfd);
#endif
函数实现
#include
#include
#include
#include
#include
#include
#include "msqlite.h"
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
int Open_Dictdb(sqlite3* dictdb)
{
int ret = -1;
if(sqlite3_open("./dict.db", &dictdb) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return ret;
}
char sql[128] = "create table if not exists dict(word char, mean char);";
char* errmsg = NULL;
if(sqlite3_exec(dictdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n", __FILE__, __LINE__, errmsg);
return ret;
}
printf("[%s] Dictdb open success\n", __DATE__);
ret = 0;
return ret;
}
int Open_Userdb(sqlite3* userdb)
{
int ret = -1;
if(sqlite3_open("./user.db", &userdb) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return 0;
}
char sql[128] = "create table if not exists user(id char PRIMARY KEY, password char);";
char* errmsg = NULL;
if(sqlite3_exec(userdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n", __FILE__, __LINE__, errmsg);
return ret;
}
ret = 0;
return ret;
}
int Open_Histroy(sqlite3* histroy)
{
int ret = -1;
if(sqlite3_open("./histroy.db", &histroy) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return ret;
}
ret = 0;
return ret;
}
int Insert_Dict(sqlite3* dictdb)
{
if(sqlite3_open("./dict.db", &dictdb) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return -1;
}
char sql[128] = "create table if not exists dict(word char, mean char);";
char* errmsg = NULL;
if(sqlite3_exec(dictdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n", __FILE__, __LINE__, errmsg);
return -1;
}
FILE* fp_r;
char word[64] = "";
char mean[64] = "";
char buf[128] = "";
int count = 0;
if((fp_r = fopen("./dict.txt", "r")) == NULL)
{
LOG("fopen error");
return -1;
}
int size = Get_File_Line("./dict.txt");
printf("词典正在录入。。。\n");
while(1)
{
bzero(buf, sizeof(buf));
bzero(mean, sizeof(mean));
bzero(word, sizeof(word));
if(size == count++)
break;
if(fgets(buf, sizeof(buf), fp_r) == NULL)
{
LOG("fgets error");
return -1;
}
buf[strlen(buf)-1] = 0;
int flag = 0;
for(int i = 0; i < strlen(buf); i++)
{
if(buf[i] == ' ' && 0 == flag)
{
strncpy(word, buf, i+1);
word[strlen(word)-1] = 0;
flag = 1;
}
if(buf[i] != ' ' && 1 == flag)
{
strcpy(mean, &buf[i]);
break;
}
}
char sql[128] = "";
sprintf(sql, "insert into dict values (\"%s\", \"%s\");", word, mean);
char* errmsg = NULL;
if(sqlite3_exec(dictdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n",__FILE__, __LINE__, errmsg);
perror("sqlite3_exec");
return -1;
}
}
printf("词典录入完成\n");
return 0;
}
int Connect_Event(sqlite3* userdb, sqlite3* histroy, Umsg_t usermsg, int cfd, ClistPtr C)
{
if(usermsg.type == 'L')
{
return User_Login(userdb, usermsg, cfd, C);
}
else if(usermsg.type == 'R')
{
return User_Register(userdb, usermsg, cfd);
}
return 0;
}
int User_Login(sqlite3* userdb, Umsg_t usermsg, int cfd, ClistPtr C)
{
int ask = -1;
if(sqlite3_open("./user.db", &userdb) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return -1;
}
char sql[128] = "create table if not exists user(id char, password char);";
char* errmsg = NULL;
if(sqlite3_exec(userdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n", __FILE__, __LINE__, errmsg);
return -1;
}
char cmp[128] = "";
sprintf(cmp,"SELECT * FROM user WHERE id like \"%s\" AND password like \"%s\"",usermsg.id,usermsg.password);
char ** pres = NULL;
int row,column;
if(sqlite3_get_table(userdb, cmp, &pres, &row, &column, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_get_table:%s\n", __FILE__, __LINE__, errmsg);
return -1;
}
ClistPtr p;
if((p = List_Search_User(C, usermsg.id)))
{
ask = 5;
if(send(cfd, &ask, sizeof(ask), 0) < 0)
{
LOG("send");
return -1;
}
printf("%s用户重复登录\n",usermsg.id);
return -1;
}
else if(row == 1)
{
ask = 1;
if(send(cfd, &ask, sizeof(ask), 0) < 0)
{
LOG("send");
return -1;
}
printf("%s用户登入成功\n",usermsg.id);
sqlite3_free_table(pres);
pres = NULL;
return 1;
}
else
{
if(send(cfd, &ask, sizeof(ask), 0) < 0)
{
LOG("send");
return -1;
}
return -1;
}
sqlite3_free_table(pres);
pres = NULL;
return -1;
}
int User_Register(sqlite3* userdb, Umsg_t usermsg, int cfd)
{
if(sqlite3_open("./user.db", &userdb) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return -1;
}
char sql[128] = "create table if not exists user(id char PRIMARY KEY, password char);";
char* errmsg = NULL;
if(sqlite3_exec(userdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec\n", __FILE__, __LINE__);
perror("");
return -1;
}
int ask = -1;
char msg[128] = "";
sprintf(msg, "insert into user values (\"%s\",\"%s\");", usermsg.id, usermsg.password);
if(sqlite3_exec(userdb, msg, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:", __FILE__, __LINE__);
perror("");
if(send(cfd, &ask, sizeof(ask), 0) < 0)
{
LOG("send");
return -1;
}
return -1;
}
ask = 1;
if(send(cfd, &ask, sizeof(ask), 0) < 0)
{
LOG("send");
return -1;
}
printf("%s用户注册成功\n",usermsg.id);
return 1;
}
int Get_File_Line(char* file)
{
int ret = -1;
int line = 0;
int ch;
FILE * path;
path = fopen(file, "r+");
if (NULL == path)
{
LOG("open file error");
return ret;
}
while((ch = fgetc(path)) != EOF)
{
if(ch == '\n')
{
line++;
}
}
return (ret = line);
}
int Search_Word(Word_t word, int cfd, Umsg_t usermsg, sqlite3* dictdb, sqlite3* histroy)
{
int ret = -1;
if(sqlite3_open("./dict.db", &dictdb) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return ret;
}
char sql[128] = "create table if not exists dict(word char, mean char);";
char* errmsg = NULL;
if(sqlite3_exec(dictdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n", __FILE__, __LINE__, errmsg);
return ret;
}
if(sqlite3_open("./histroy.db", &histroy) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return ret;
}
bzero(sql, sizeof(sql));
sprintf(sql, "create table if not exists %s(word char, mean char, time char);", usermsg.id);
if(sqlite3_exec(histroy, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:\n", __FILE__, __LINE__);
perror("");
return ret;
}
char cmp[128] = "";
sprintf(cmp,"SELECT * FROM dict WHERE word like \"%s\" OR mean like \" %s \"",word.word,word.mean);
char ** pres = NULL;
int row,column;
if(sqlite3_get_table(dictdb, cmp, &pres, &row, &column, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_get_table:%s\n", __FILE__, __LINE__, errmsg);
return ret;
}
if(row == 0)
{
strcpy(word.mean, "未查询到此单词,请重试");
}
else
{
bzero(&word,sizeof(word));
strcpy(word.word,pres[2]);
strcpy(word.mean,pres[3]);
time_t t;
struct tm *info = NULL;
char timenow[128] = "";
t = time(NULL);
info = localtime(&t);
sprintf(timenow, "[%d-%02d-%02d] %02d:%02d:%02d",\
info->tm_year+1900, \
info->tm_mon+1, \
info->tm_mday,\
info->tm_hour, \
info->tm_min, \
info->tm_sec);
char sql[128] = "";
bzero(sql,sizeof(sql));
sprintf(sql, "insert into %s values(\"%s\",\"%s\",\"%s\");", usermsg.id, pres[2], pres[3], timenow);
if(sqlite3_exec(histroy, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_exec:%s\n", __FILE__, __LINE__, errmsg);
return ret;
}
}
if(send(cfd, &word, sizeof(word), 0) < 0)
{
LOG("send");
return ret;
}
ret = 0;
return ret;
}
int Show_History(sqlite3* histroy, Umsg_t usermsg, int cfd)
{
char cmp[128] = "";
Word_t word;
if(sqlite3_open("./histroy.db", &histroy) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_open failed\n", __FILE__, __LINE__);
return -1;
}
sprintf(cmp,"SELECT * FROM %s;", usermsg.id);
char* errmsg = NULL;
char ** pres = NULL;
int row,column;
if(sqlite3_get_table(histroy, cmp, &pres, &row, &column, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "{%s:%d} sqlite3_get_table:%s\n", __FILE__, __LINE__, errmsg);
return -1;
}
if(row > 0)
{
for(int i = 3; i <= row*column; i+=3)
{
strcpy(word.word, pres[i]);
strcpy(word.mean, pres[i+1]);
strcpy(word.time, pres[i+2]);
if(send(cfd, &word, sizeof(word), 0) < 0)
{
LOG("send");
return -1;
}
}
strcpy(word.mean, "over");
if(send(cfd, &word, sizeof(word), 0) < 0)
{
LOG("send");
return -1;
}
return 1;
}
else
{
strcpy(word.mean, "暂无历史记录");
if(send(cfd, &word, sizeof(word), 0) < 0)
{
LOG("send");
return -1;
}
}
return 0;
}
链表头文件
#ifndef _CLIENT_LIST_H_
#define _CLIENT_LIST_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct node
{
union
{
struct sockaddr_in caddr;
int len;
};
char id[20];
struct node* next;
} Clist, *ClistPtr;
ClistPtr List_Create();
int List_Empty(ClistPtr C);
ClistPtr Node_Buy(struct sockaddr_in caddr, char* id);
void List_Insert_Head(ClistPtr C, struct sockaddr_in caddr, char* id);
void List_Delete(ClistPtr C, struct sockaddr_in caddr);
void List_Free(ClistPtr *C);
ClistPtr List_Search_User(ClistPtr C, char* id);
#endif
链表函数实现
#include "Client_list.h"
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
ClistPtr List_Create()
{
ClistPtr C = (ClistPtr)malloc(sizeof(Clist));
if(NULL == C)
{
LOG("malloc memory file!");
return NULL;
}
C->len = 0;
C->next = NULL;
puts("list create compelet!");
return C;
}
int List_Empty(ClistPtr C)
{
if(NULL == C)
{
LOG("malloc memory file!");
return -1;
}
return C->next == NULL && C->len == 0;
}
ClistPtr Node_Buy(struct sockaddr_in caddr, char* id)
{
ClistPtr P = (ClistPtr)malloc(sizeof(Clist));
if(NULL == P)
{
LOG("malloc memory file!");
return NULL;
}
P->caddr = caddr;
strcpy(P->id, id);
P->next = NULL;
return P;
}
void List_Insert_Head(ClistPtr C, struct sockaddr_in caddr, char* id)
{
if(NULL == C)
{
LOG("malloc memory file!");
return ;
}
ClistPtr P = Node_Buy(caddr, id);
if(NULL == P)
{
LOG("malloc memory file!");
return ;
}
P->next = C->next;
C->next = P;
C->len++;
}
void List_Delete(ClistPtr C, struct sockaddr_in caddr)
{
if(NULL == C || List_Empty(C))
{
LOG("memory error!");
return;
}
ClistPtr q = C;
ClistPtr p = NULL;
while(q->next != NULL)
{
if(!memcmp(&q->next->caddr, &caddr, sizeof(caddr)))
{
break;
}
q = q->next;
}
p = q->next;
q->next = q->next->next;
p->next = NULL;
free(p);
p = NULL;
C->len--;
}
void List_Free(ClistPtr *C)
{
if(NULL == C || NULL == *C)
{
LOG("memory error!");
return;
}
ClistPtr q = *C;
while(*C != NULL)
{
q = q->next;
free(*C);
*C = q;
}
puts("list free");
}
ClistPtr List_Search_User(ClistPtr C, char* id)
{
ClistPtr q = C->next;
for(int i=1; i<=C->len; i++)
{
if(strcmp(q->id,id))
{
q = q ->next;
}
else
{
return q;
}
}
return NULL;
}
客户端功能头文件
#ifndef __CLIENT_H__
#define __CLIENT_H__
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "server.h"
int Menu(int client);
int Login(int client);
int Register(int client);
int Search(int client);
int History(int client);
#endif
客户端功能实现
#include "client.h"
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
Umsg_t usermsg;
int Menu(int client)
{
int ret;
while(1)
{
system("clear");
printf("-----------1.登入------------\n");
printf("-----------2.注册------------\n");
printf("-----------3.退出------------\n");
char choose;
printf("请选择:");
scanf("%c",&choose);
while(getchar() != 10);
switch(choose)
{
case '1':
ret = Login(client);
return ret;
break;
case '2':
ret = Register(client);
return ret;
break;
case '3':
return 1;
default:
printf("输入错误,请重新输入\n");
}
printf("输入任意字符清屏>>>");
while(getchar() != 10);
}
return ret;
}
int Login(int client)
{
while(1)
{
printf("------登录------\n");
usermsg.type = 'L';
printf("请输入账号>>>");
scanf("%s",usermsg.id);
while(getchar() != 10);
printf("请输入密码>>>");
scanf("%s",usermsg.password);
while(getchar() != 10);
system("clear");
printf("登陆中。。。");
if(send(client, &usermsg , sizeof(usermsg), 0) < 0)
{
LOG("send");
return -1;
}
int flag;
ssize_t res;
res = recv(client, &flag, sizeof(flag), 0);
if(res < 0)
{
LOG("recv");
return -1;
}
else if(0 == res)
{
return -1;
}
system("clear");
if(flag == 5)
{
printf("重复登录\n");
}
else if(flag == 1)
{
printf("登入成功\n");
break;
}
else if(flag == -1)
{
printf("用户账号密码错误\n");
}
}
return 0;
}
int Register(int client)
{
printf("------注册------\n");
while(1)
{
usermsg.type = 'R';
printf("请输入注册账号:");
scanf("%s",usermsg.id);
while(getchar() != 10);
printf("请输入注册密码:");
scanf("%s",usermsg.password);
while(getchar() != 10);
if(send(client, &usermsg , sizeof(usermsg), 0) < 0)
{
LOG("send");
return -1;
}
int flag;
ssize_t res;
res = recv(client, &flag, sizeof(flag), 0);
if(res < 0)
{
LOG("recv");
return -1;
}
else if(0 == res)
{
printf("server is off-line\n");
return -1;
}
if(flag == 1)
{
printf("注册成功\n");
break;
}
else if(flag < 0)
{
printf("注册失败,重复注册\n");
}
}
return 0;
}
int Search(int client)
{
char buf[128] = "";
ssize_t res = 0;
Word_t words;
usermsg.type = 'S';
if(send(client, &usermsg , sizeof(usermsg), 0) < 0)
{
LOG("send");
return -1;
}
system("clear");
while(1)
{
bzero(&words,sizeof(words));
bzero(buf, sizeof(buf));
printf("请输入要查询的单词>>>");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0;
strcpy(words.word,buf);
if(send(client, &words, sizeof(words), 0) < 0)
{
LOG("send");
return -1;
}
system("clear");
bzero(&words, sizeof(words));
res = recv(client, &words, sizeof(words), 0);
if(res < 0)
{
LOG("recv");
return -1;
}
else if(0 == res)
{
printf("服务器已掉线\n");
break;
}
printf("%s\t%s\n", words.word, words.mean);
}
return 0;
}
int History(int client)
{
Word_t word;
usermsg.type = 'H';
if(send(client, &usermsg , sizeof(usermsg), 0) < 0)
{
LOG("send");
return -1;
}
system("clear");
while(1)
{
bzero(&word, sizeof(word));
int res = recv(client, &word, sizeof(word), 0);
if(res < 0)
{
LOG("recv");
return -1;
}
else if(0 == res)
{
printf("服务器已掉线\n");
return -1;
}
if(!strcmp(word.mean, "over"))break;
printf("%s\t%s\t\t%s\n", word.word, word.mean, word.time);
}
printf("输入任意字符清屏>>>");
while(getchar() != 10);
system("clear");
return 0;
}
客户端main函数
#include "client.h"
#include
#define PORT 8888
#define IP "192.168.114.73"
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
int main(int argc, const char *argv[])
{
int cfd = socket(AF_INET, SOCK_STREAM, 0);
if(cfd < 0)
{
LOG("socket");
return -1;
}
printf("create socket success\n");
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PORT);
saddr.sin_addr.s_addr = inet_addr(IP);
if(connect(cfd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0)
{
LOG("connect");
return -1;
}
int ret = 0;
while(1)
{
ret = Menu(cfd);
if(ret== 0)
{
printf("connect success\n");
}
else if(ret == -1)
{
printf("服务器掉线\n");
return -1;
}
else
{
return -1;
}
while(1)
{
system("clear");
printf("-----------1.查单词------------\n");
printf("-----------2.历史记录----------\n");
char choose;
printf("请选择:");
scanf("%c",&choose);
while(getchar() != 10);
switch(choose)
{
case '1':
Search(cfd);
break;
case '2':
History(cfd);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
printf("输入任意字符清屏>>>");
while(getchar() != 10);
}
}
close(cfd);
return 0;
}
服务器功能函数
#ifndef SERVER_H
#define SERVER_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "msqlite.h"
#include "Client_list.h"
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
void* loop_printf(void* arg);
void list_show(ClistPtr C);
#endif
服务器函数实现
#include "server.h"
void* loop_printf(void* arg)
{
ClistPtr C = arg;
pthread_detach(pthread_self());
while(1)
{
system("clear");
list_show(C);
sleep(3);
}
pthread_exit(NULL);
}
void list_show(ClistPtr C)
{
time_t t;
struct tm *info = NULL;
char timenow[128] = "";
t = time(NULL);
info = localtime(&t);
sprintf(timenow, "[%d-%02d-%02d] %02d:%02d:%02d",\
info->tm_year+1900, \
info->tm_mon+1, \
info->tm_mday,\
info->tm_hour, \
info->tm_min, \
info->tm_sec);
if( NULL == C || List_Empty(C) )
{
printf("时间: %s\t暂无用户\n", timenow);
return;
}
printf("时间: %s\t在线用户个数%d:\n",timenow, C->len);
ClistPtr q = C->next;
while(q != NULL)
{
printf("IP: %s\t|\tPort: %d\t|\tId: %s\n", inet_ntoa(q->caddr.sin_addr), ntohs(q->caddr.sin_port), q->id);
q = q->next;
}
printf("\n");
}
服务器主函数
#include "server.h"
#define PORT 8888
#define IP "192.168.114.73"
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s);
void* Rcv_Msg(void* arg)
{
pthread_detach(pthread_self());
sqlite3* userdb;
sqlite3* histroy;
sqlite3* dictdb;
int cfd = (*(Msg_t*)arg).cfd;
struct sockaddr_in caddr = (*(Msg_t*)arg).caddr;
ClistPtr C = (*(Msg_t*)arg).C;
Umsg_t usermsg;
while(1)
{
ssize_t res;
bzero(&usermsg, sizeof(usermsg));
res = recv(cfd, &usermsg, sizeof(usermsg), 0);
if(res < 0)
{
LOG("recv");
return NULL;
}
else if(0 == res)
{
printf("[%s] [%s / %d] client: %d 客户端离线\n", __DATE__, inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port), cfd);
close(cfd);
pthread_exit(NULL);
return NULL;
}
if( ( Connect_Event(userdb, histroy, usermsg, cfd, C)) == 1)
{
break;
}
}
List_Insert_Head(C , caddr, usermsg.id);
while(1)
{
ssize_t res;
bzero(&usermsg, sizeof(usermsg));
res = recv(cfd, &usermsg, sizeof(usermsg), 0);
if(res < 0)
{
LOG("recv");
return NULL;
}
else if(0 == res)
{
printf("[%s] [%s / %d] client: %d 客户端离线\n", __DATE__, inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port), cfd);
List_Delete(C, caddr);
close(cfd);
pthread_exit(NULL);
return NULL;
}
if(usermsg.type == 'H')
{
Show_History(histroy, usermsg, cfd);
continue;
}
else if(usermsg.type == 'S')
{
Word_t words;
char buf[128] = "";
while(1)
{
bzero(&words,sizeof(words));
bzero(buf, sizeof(buf));
res = recv(cfd, &words, sizeof(words), 0);
if(res < 0)
{
LOG("recv");
break;
}
else if(0 == res)
{
printf("[%s : %d] newfd = %d 客户端掉线\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port), cfd);
List_Delete(C, caddr);
close(cfd);
pthread_exit(NULL);
return NULL;
}
Search_Word(words, cfd, usermsg, dictdb, histroy);
}
}
}
}
int main(int argc, const char *argv[])
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd < 0)
{
LOG("socket");
return -1;
}
printf("create socket success\n");
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
LOG("setsockopt");
return -1;
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PORT);
saddr.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0)
{
LOG("bind");
return -1;
}
printf("bind success\n");
if(listen(sfd, 10) < 0)
{
LOG("listen");
return -1;
}
printf("listen success\n");
sqlite3* dictdb;
sqlite3* userdb;
sqlite3* histroy;
Open_Dictdb(dictdb);
Open_Userdb(userdb);
Open_Histroy(histroy);
ClistPtr C = List_Create();
if(NULL == C)
{
return -1;
}
struct sockaddr_in caddr;
socklen_t addrlen = sizeof(caddr);
int newfd = 0;
pthread_t tid;
Msg_t msg;
if(pthread_create(&tid, NULL, loop_printf, (void*)C) != 0)
{
LOG("pthread_create");
return -1;
}
while(1)
{
newfd = accept(sfd, (struct sockaddr*)&caddr, &addrlen);
if(newfd < 0)
{
LOG("accept");
return -1;
}
printf("[%s : %d] newfd = %d 客户端连入\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),newfd);
msg.cfd = newfd;
msg.caddr = caddr;
msg.C = C;
if(pthread_create(&tid, NULL, Rcv_Msg, (void*)&msg) != 0)
{
LOG("pthread_create");
return -1;
}
}
close(sfd);
List_Free(&C);
return 0;
}