#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
#include <sqlite3.h>
#include <wait.h>
#include <signal.h>
#include "lock.h"
#define MY_PORT 3333
#define MAXSIZE 1024
//#define DEBUG
//
void sendbegin(int accept_fd,char *p)
{
int sendbytes;
if((sendbytes=send(accept_fd,p,MAXSIZE,0))== -1)
{
fprintf(stderr,"Send Error:%s\n",strerror(errno));
exit(1);
}
//printf("发送道客户端 %s\n",p);
}
int recvbegin(int accept_fd,char *q,char *x)
{
int recvbytes;
if((recvbytes=recv(accept_fd,q,MAXSIZE,0))== -1)
{
fprintf(stderr,"recv error%s\n",strerror(errno));
exit(1);
}
//printf("从客户端接收到 q=%s ,x=%s\n",q,x);
return(strcmp(q,x));
}
int insert(char *m,char*n)
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("clientmsg.db", &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s/n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
else printf("成功打开数据库 ^-^ \n");
char *sql = sqlite3_mprintf("INSERT INTO clientmsg VALUES ('%q','%q')",m,n);
sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );
sqlite3_close(db);
return 0;
}
int selectcmp(char *m,char *n)
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;
int nrow,ncolumn;
char **azResult;
rc = sqlite3_open("clientmsg.db", &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s/n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
else printf("有用户接入,成功打开用户信息数据库 ^-^ \n");
char *sql = sqlite3_mprintf("SELECT %q from clientmsg where %q = '%q'",m,m,n);
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
//printf("nrow=%d\n",nrow);
if(nrow>0)
{return 1;
sqlite3_free_table( azResult );
}
else {
return 0;
sqlite3_free_table( azResult );
}
}
int selectcmp_double(char *m,char *n)
{
sqlite3 *db=NULL;
char *zErrMsg = 0;
int rc;
int nrow,ncolumn;
char **azResult;
rc = sqlite3_open("clientmsg.db", &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s/n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
else printf("成功打开数据库 ^-^ \n");
printf("m=%s\n",m);
printf("n=%s\n",n);
char *sql = sqlite3_mprintf("SELECT pwd from clientmsg where user = '%q' and pwd='%q'" ,m,n);
sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );
int i;
printf( "row=%d column=%d \n" , nrow , ncolumn );
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf( "azResult[%d] = %s\n", i , azResult[i] );
if(nrow>0)
{return 1;
sqlite3_free_table( azResult );
}
else {
return 0;
sqlite3_free_table( azResult );
}
}
//此函数将收到的用户答案进行收集打印。
int recvinfo(int accept_fd,char *p,int answer,char *client,char **q,int *correct)
{
int recvbytes;
int fd;
char buf[128];
memset(buf,'\0',128);
fd=open("iqlog",O_RDWR|O_CREAT,0666);
if(fd<0)
{
perror("open");
exit(1);
}
if((recvbytes=recv(accept_fd,p,MAXSIZE,0))== -1)
{
fprintf(stderr,"recv error%s\n",strerror(errno));
exit(1);
}
if(strcmp(p,q[answer*7+6])!=0)
{printf("%s回答第%d题是错的, 已经答对%d道题\n",client,answer,(*correct));
lock_set(fd,F_WRLCK);
sprintf(buf,"client %s's answer %d is wrong ,he has %d correct\n",client,answer,(*correct));
lseek(fd,0,SEEK_END);
if( write(fd,buf,sizeof(buf))==-1)
{
fprintf(stderr,"Write Error:%s\n",strerror(errno));
exit(1);
}
lock_set(fd,F_UNLCK);
close(fd);
return;
}
else {printf("%s回答第%d题是对的,已经答对%d道题\n",client,answer,++(*correct));
lock_set(fd,F_WRLCK);
sprintf(buf,"client %s's answer %d is right ,he has %d correct\n",client,answer,(*correct));
lseek(fd,0,SEEK_END);
if( write(fd,buf,sizeof(buf))==-1)
{
fprintf(stderr,"Write Error:%s\n",strerror(errno));
exit(1);
}
lock_set(fd,F_UNLCK);
close(fd);
return;
}
}
//此函数将服务器上的题目送往客户端。
void sendinfo(int accept_fd,char **q,int question,char *client )
{
int sendbytes;
int i;
for(i=1;i<6;i++)
{
if((sendbytes=send(accept_fd,q[question*7+i],MAXSIZE,0))== -1)
{
fprintf(stderr,"Send Error:%s\n",strerror(errno));
exit(1);
}
}
printf("问题 %d 已传送给%s\n",question,client);
}
//此函数为线程调用函数
void * question_init()
{//本线程完成从数据库读取题目并返回到主进程。
printf("**********测试程序已开启,请使用CTRL+C进行退出**********\n\n\n");
sqlite3 *db=NULL;
int rc;
char *ErrMsg = 0;
rc = sqlite3_open("iqtest.db", &db);
if( rc )
{
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
else printf("********************\n成功打开数据库\n******************** \n");
char *sql;//定义数据库语言
int nrow = 0, ncolumn = 0;
char **Result;
sql = "SELECT * FROM iqtest ";
sqlite3_get_table( db , sql , &Result , &nrow , &ncolumn , &ErrMsg );
#ifdef DEBUG
printf( "row:%d column=%d \n" , nrow , ncolumn );
printf( "\n**********\n数据库遍历如下\n********** : \n" );
int i = 0 ;
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
printf("result[%d]=%s\n",i,Result[i]);
#endif
sqlite3_close(db);
printf("********************\n调用并返回数据库完毕\n********************\n");
pthread_exit((void*) Result);
}
int main(int argc ,char **argv)
{
pthread_t question_init_tid;
int ret;
if((ret=pthread_create(&question_init_tid,NULL,question_init,NULL))== -1)
{
printf("pthread create error:\n",strerror(errno));
exit(1);
}
int listen_fd,accept_fd;
struct sockaddr_in client_addr;
int n,recvbytes;
char hello[]="你将要回答几个问题。请选择A、B、C或D.";
if((listen_fd=socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("Socket Error:%s\n\a",strerror(errno));
exit(1);
}
bzero(&client_addr,sizeof(struct sockaddr_in));
client_addr.sin_family=AF_INET;
client_addr.sin_port=htons(MY_PORT);
client_addr.sin_addr.s_addr=htonl(INADDR_ANY);
n=1;
setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));
if(bind(listen_fd,(struct sockaddr *)&client_addr,sizeof(client_addr))<0)
{
printf("Bind Error:%s\n\a",strerror(errno));
exit(1);
}
char **retval;
pthread_join(question_init_tid,(void**)&retval);
printf("\n*********test over******** \n");
listen(listen_fd,5);
while(1)
{
accept_fd=accept(listen_fd,NULL,NULL);
if((accept_fd<0)&&(errno==EINTR))
continue;
else if(accept_fd<0)
{
printf("Accept Error:%s\n\a",strerror(errno));
continue;
}
// signal(SIGQUIT,my_quit);
//创建子进程
pid_t pc,pr;
pc=fork();
if(pc<0)
printf("Fork Error:%s\n\a",strerror(errno));
else if(pc==0)
{
sqlite3 *db=NULL;
char sign[]="signin";
char login[]="login";
char t[MAXSIZE];
char OK[]="OK";
char BAD[]="BAD";
int m;
m=recvbegin(accept_fd,t,sign);
char bufuser[MAXSIZE];
char bufpwd[MAXSIZE];
int recvbytes;
// printf("m=%d\n",m);
if(m==0)
{
sendbegin(accept_fd,sign);
while(1)
{
if((recvbytes=recv(accept_fd,bufuser,MAXSIZE,0))== -1)
{
fprintf(stderr,"recv error%s\n",strerror(errno));
sendbegin(accept_fd,BAD);
continue;
}
int exist;
if((exist=selectcmp("user