- 在传结构体时要注意结构体的大小,以及服务器和客户端双方的互传的结构体是否一样
- 在操作数据库的时候注意要有打开数据库的这一条件
- 注意
sqlite3_get_table函数的返回值,用这个判断表里是否查询成功时是根据nrow的返回值来判断的
- 编译时记得链接库
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define N 128
#define ERRLOG(errmsg) do{\
perror(errmsg);\
printf("%s - %s - %d\n", __FILE__, __func__, __LINE__);\
exit(1);\
}while(0)
typedef struct{
int code;
int acceptfd;
char user_name[N];
char user_password[N];
char word[N];
char timebuf[18];
struct sockaddr_in clientaddr;
}MSG;
void user_register(MSG msg,int sockfd);
void user_login(MSG msg,int sockfd);
void query_word(MSG msg,int sockfd);
int main(int argc, char const *argv[])
{
if(argc < 3)
{
fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
exit(1);
}
int sockfd;
char chose;
struct sockaddr_in serveraddr;
socklen_t addrlen = sizeof(serveraddr);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
ERRLOG("socket error");
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) == -1)
{
ERRLOG("connect error");
}
MSG msg;
char buf[N] = {0};
while(1)
{
START:
printf("***********************************\n");
printf("**1:register 2:login 3:quit**\n");
printf("***********************************\n");
scanf("%d",&msg.code);
getchar();
if(msg.code == 3)break;
switch(msg.code)
{
case 1:
user_register(msg,sockfd);
break;
case 2:
user_login(msg,sockfd);
break;
default:
break;
}
}
return 0;
}
void user_register(MSG msg,int sockfd)
{
printf("input your name:");
fgets(msg.user_name, sizeof(msg), stdin);
msg.user_name[strlen(msg.user_name) - 1] = '\0';
printf("input your password:");
fgets(msg.user_password, sizeof(msg), stdin);
msg.user_password[strlen(msg.user_password) - 1] = '\0';
if(send(sockfd, &msg, sizeof(msg), 0) == -1)
{
ERRLOG("send error");
}
char buf[N];
if(recv(sockfd, buf, N, 0) == -1)
{
ERRLOG("recv error");
}
printf("%s\n",buf);
}
void user_login(MSG msg,int sockfd)
{
printf("input your name:");
fgets(msg.user_name, sizeof(msg), stdin);
msg.user_name[strlen(msg.user_name) - 1] = '\0';
printf("input your password:");
fgets(msg.user_password, sizeof(msg), stdin);
msg.user_password[strlen(msg.user_password) - 1] = '\0';
if(send(sockfd, &msg, sizeof(msg), 0) == -1)
{
ERRLOG("send error");
}
char buf[N];
if(recv(sockfd, buf, N, 0) == -1)
{
ERRLOG("recv error");
}
else
{
printf("%s\n",buf);
}
query_word(msg,sockfd);
}
void query_word(MSG msg,int sockfd)
{
if(recv(sockfd, &msg, N, 0) == -1)
{
ERRLOG("recv error");
}
switch(msg.code)
{
case 5:
break;
case 6:
while(1)
{
NEXT:
printf("***********************************\n");
printf("**1:query 2:history 3:quit**\n");
printf("***********************************\n");
printf("please choose :");
scanf("%d",&msg.code);
while(getchar()!='\n');
if(msg.code == 3)break;
switch(msg.code)
{
case 1:
{
msg.code = 3;
printf("input word :");
fgets(msg.word, sizeof(msg), stdin);
msg.word[strlen(msg.word) - 1] = '\0';
if(send(sockfd, &msg, sizeof(msg), 0) == -1)
{
ERRLOG("send error");
}
char buf[500] = {0};
if(recv(sockfd, buf, 500, 0) == -1)
{
ERRLOG("recv error");
}
else
{
printf("%s\n",buf);
}
}
break;
case 2:
{
msg.code = 4;
if(send(sockfd, &msg, sizeof(msg), 0) == -1)
{
ERRLOG("send error");
}
char buf[N];
while(1)
{
if(recv(sockfd, buf, N, 0) == -1)
{
ERRLOG("recv error");
}
if(strcmp(buf,"next") == 0)goto NEXT;
printf("%s\n",buf);
}
}
break;
default:
break;
}
}
break;
default:
break;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sqlite3.h>
#include <time.h>
#define DBFILE "dict.db"
#define TABLE1 "user"
#define TABLE2 "word"
#define N 128
#define ERRLOG(errmsg) do{\
perror(errmsg);\
printf("%s-%s-%d\n", __FILE__, __func__, __LINE__);\
exit(1);\
}while(0)
typedef struct{
int code;
int acceptfd;
char user_name[N];
char user_password[N];
char word[N];
char timebuf[N];
struct sockaddr_in clientaddr;
}MSG;
void creat_user_list(sqlite3 *db);
void creat_word_list(sqlite3 *db);
void user_register(MSG msg,sqlite3 *db,int sockfd);
void user_login(MSG msg, sqlite3 *db, int sockfd);
void do_get_table(sqlite3 *db);
void query_word(MSG msg,sqlite3 *db,int sockfd);
void history_word(MSG msg, sqlite3 *db, int sockfd);
MSG query_time(MSG msg);
void *pthread_fun(void *arg)
{
MSG msg = *(MSG *)arg;
int acceptfd = msg.acceptfd;
struct sockaddr_in clientaddr = msg.clientaddr;
pthread_detach(pthread_self());
char buf[N] = {0};
ssize_t bytes;
sqlite3 *db1;
sqlite3 *db2;
while(1)
{
if(recv(acceptfd, &msg, sizeof(msg), 0) == -1)
{
ERRLOG("recv error");
}
switch(msg.code)
{
case 1:
user_register(msg,db1,acceptfd);
msg.code = 0;
break;
case 2:
user_login(msg,db1,acceptfd);
msg.code = 0;
break;
case 3:
query_word(msg,db2,acceptfd);
msg.code = 0;
break;
case 4:
history_word(msg,db2,acceptfd);
msg.code = 0;
break;
default:
break;
}
}
}
int main(int argc, char const *argv[])
{
if(argc < 3)
{
fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
exit(1);
}
int sockfd, acceptfd;
struct sockaddr_in serveraddr;
socklen_t addrlen = sizeof(struct sockaddr_in);
struct sockaddr_in clientaddr;
sqlite3 *db1;
sqlite3 *db2;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
ERRLOG("socket error");
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));
if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) == -1)
{
ERRLOG("bind error");
}
if(listen(sockfd, 5) == -1)
{
ERRLOG("listen error");
}
pthread_t thread;
MSG msg;
creat_user_list(db1);
creat_word_list(db2);
while(1)
{
if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
{
ERRLOG("accept error");
}
msg.acceptfd = acceptfd;
msg.clientaddr = clientaddr;
if(pthread_create(&thread, NULL, pthread_fun, &msg) != 0)
{
ERRLOG("pthread_create error");
}
}
return 0;
}
void creat_user_list(sqlite3 *db)
{
if(sqlite3_open(DBFILE ,&db) != SQLITE_OK)
{
printf("error:%s\n",sqlite3_errmsg(db));
exit(1);
}
char sql[128] = {0};
char *errmsg;
sprintf(sql, "create table %s(name text primary key, password text)", TABLE1);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
else
{
printf("成功:用户表创建成功\n");
}
}
void creat_word_list(sqlite3 *db)
{
if(sqlite3_open(DBFILE ,&db) != SQLITE_OK)
{
printf("error:%s\n",sqlite3_errmsg(db));
exit(1);
}
char sql[128] = {0};
char *errmsg;
sprintf(sql, "create table %s(name char, time char, word char)", TABLE2);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
}
void user_register(MSG msg, sqlite3 *db, int sockfd)
{
char sql[512] = {0};
char *errmsg;
if(sqlite3_open(DBFILE ,&db) != SQLITE_OK)
{
printf("error:%s\n",sqlite3_errmsg(db));
exit(1);
}
sprintf(sql, "insert into %s values('%s', '%s')", TABLE1, msg.user_name,msg.user_password);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
char buf[512];
sprintf(buf,"register :user %s alredy exist!\n",msg.user_name);
if(send(sockfd, buf, N, 0) == -1)
{
ERRLOG("send error");
}
}
else
{
char buf[12] = "register:OK";
if(send(sockfd, buf, N, 0) == -1)
{
ERRLOG("send error");
}
}
}
void user_login(MSG msg, sqlite3 *db, int sockfd)
{
char sql[512] = {0};
char **ret;
char *errmsg;
int nrow, ncolumn;
if(sqlite3_open(DBFILE ,&db) != SQLITE_OK)
{
printf("error:%s\n",sqlite3_errmsg(db));
exit(1);
}
sprintf(sql, "select * from %s where name='%s' and password='%s'", TABLE1,msg.user_name,msg.user_password);
if(sqlite3_get_table(db, sql, &ret, &nrow, &ncolumn, &errmsg) != SQLITE_OK)
{
}
if (nrow == 0)
{
msg.code = 5;
char buf[N] = "name or password is wrony!";
if(send(sockfd, buf, N, 0) == -1)
{
ERRLOG("send error");
}
if(send(sockfd, &msg, N, 0) == -1)
{
ERRLOG("send error");
}
}
else
{
msg.code = 6;
char buf[N] = "login success!";
if(send(sockfd, buf, N, 0) == -1)
{
ERRLOG("send error");
}
if(send(sockfd, &msg, N, 0) == -1)
{
ERRLOG("send error");
}
}
}
void query_word(MSG msg, sqlite3 *db, int sockfd)
{
FILE *fp;
char *errmsg;
char temp[300] = {0};
char explainbuf[512] = {0};
char sql[512] = {0};
char *p;
int len, result;
len = strlen(msg.word);
if((fp = fopen("dict.txt", "r")) == NULL)
{
strcpy(msg.word, "dict can not open");
send(sockfd, &msg, sizeof(MSG), 0);
}
while(fgets(temp, 300, fp) != NULL)
{
result = strncmp(msg.word, temp, len);
if(result == 0 && temp[len] == ' ')
{
p = temp + len;
while(*p == ' ')
{
p++;
}
sprintf(explainbuf,"%s:%s",msg.word,p);
if(send(sockfd, explainbuf, sizeof(explainbuf), 0) == -1)
{
ERRLOG("send error");
}
fclose(fp);
msg = query_time(msg);
if(sqlite3_open(DBFILE, &db) != SQLITE_OK)
{
printf("error:%s\n", sqlite3_errmsg(db));
exit(1);
}
sprintf(sql, "insert into %s values( '%s', '%s', '%s')", TABLE2, msg.user_name, msg.timebuf, msg.word);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
printf("错误:%s\n", errmsg);
}
}
}
}
void history_word(MSG msg, sqlite3 *db, int sockfd)
{
char *errmsg;
char **ret;
char sql[512] = {0};
int nrow, ncolumn;
int flag = 1;
if(sqlite3_open(DBFILE, &db) != SQLITE_OK)
{
printf("error:%s\n", sqlite3_errmsg(db));
exit(1);
}
sprintf(sql, "select *from %s where name='%s'", TABLE2, msg.user_name);
if(sqlite3_get_table(db, sql, &ret, &nrow, &ncolumn, &errmsg) == SQLITE_OK)
{
int i, n = 4;
for(i = 0; i < nrow; i++)
{
char buf[512] = {0};
sprintf(buf,"%s : %s",ret[n],ret[n+1]);
n = n+3;
if (send(sockfd, buf, N, 0) == -1)
{
ERRLOG("send error");
}
}
char buf1[5] = "next";
if (send(sockfd, buf1, sizeof(msg), 0) == -1)
{
ERRLOG("send error");
}
}
}
MSG query_time(MSG msg)
{
time_t mytime;
mytime = time(NULL);
struct tm * mytm = localtime(&mytime);
if(NULL == mytm)
{
perror("localtime");
}
sprintf(msg.timebuf,"%d-%d-%d %d:%d:%d ",
mytm->tm_year+1900,mytm->tm_mon+1,mytm->tm_mday,
mytm->tm_hour,mytm->tm_min,mytm->tm_sec);
return msg;
}