博客:http://blog.csdn.net/muyang_ren
为什么做项目?
1、巩固之前所学的知识,查漏补缺
2、通过做项目,锻炼在实际项目中解决问题的能力
3、锻炼与他人合作的能力
服务器要求:
1、保存客户的信息
2、从数据库读出菜谱,发送给客户端
3、保存客户订单
项目职责:服务器由同学完成
项目平台和技术:ubuntu 、socket、json、sqlite、多线程 、内核链表
list.h
#ifndef __LIST_H
#define __LIST_H
/* This file is from Linux Kernel (include/linux/list.h)
* and modified by simply removing hardware prefetching of list items.
* Here by copyright, credits attributed to wherever they belong.
* Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu)
*/
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions (“__xxx”) are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200
struct list_head
{
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add (struct list_head *new, struct list_head *prev, struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add – add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add (struct list_head *new, struct list_head *head)
{
__list_add (new, head, head->next);
}
/**
* list_add_tail – add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail (struct list_head *new, struct list_head *head)
{
__list_add (new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del (struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del – deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del (struct list_head *entry)
{
__list_del (entry->prev, entry->next);
entry->next = (void *) 0;
entry->prev = (void *) 0;
}
/**
* list_del_init – deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init (struct list_head *entry)
{
__list_del (entry->prev, entry->next);
INIT_LIST_HEAD (entry);
}
/**
* list_move – delete from one list and add as another’s head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move (struct list_head *list, struct list_head *head)
{
__list_del (list->prev, list->next);
list_add (list, head);
}
/**
* list_move_tail – delete from one list and add as another’s tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail (struct list_head *list, struct list_head *head)
{
__list_del (list->prev, list->next);
list_add_tail (list, head);
}
/**
* list_empty – tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty (struct list_head *head)
{
return head->next == head;
}
static inline void __list_splice (struct list_head *list, struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice – join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice (struct list_head *list, struct list_head *head)
{
if (!list_empty (list))
__list_splice (list, head);
}
/**
* list_splice_init – join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init (struct list_head *list, struct list_head *head)
{
if (!list_empty (list)) {
__list_splice (list, head);
INIT_LIST_HEAD (list);
}
}
/**
* list_entry – get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe – iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member)) #endif
server.h
#ifndef __SERVER_H__
#define __SERVER_H__
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include <netdb.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/time.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stddef.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include </usr/local/include/json/json.h>
#include <sqlite3.h>
#include <error.h>
#include <pthread.h>
#include <semaphore.h>
/*debug define*/
#define DEBUG 0
#define JSON 1
/*socket define*/
#define LISTEN_NUM 5
#define SERVER_PORT "8888"
#define THREADNUM 100
int cli_fd;
int total_money;
int total_client;
/*sem*/
sem_t sem;
/*database*/
sqlite3 *db;
pthread_mutex_t mutex;
void cust(int tb_id,char *cust_name);
void insert_cust(char *cust_name,int fd_id, char *fd_name, int prices);
void add(int fd_id,char *cust_name);//实现加菜功能
void update_cust(char *cust_name);
void cust_delete(char *cust_name_delete);
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
struct message
{
long msg_type;
char msg_text[BUFSIZ];
};
/*init funs*/
extern int init_msg(struct message *msg);
extern void init_sock(int *sock_fd,struct sockaddr_in *sin, char *ip);
extern void init_sql();
extern void table_init();
/*thread funs*/
void *fun(void *arg);
void *cook_fun(void *arg);
/*kenel list*/
struct kool_list
{
struct list_head list;
int from;
int to;
};
/*work fun*/
void display(int worksds);
void *work_fun(void *arg);
char buf_cook[BUFSIZ];
char buf_cli[BUFSIZ];
#endif
server.c
#include "server.h"
#define WORK 1
/*main------------------------------------------------------------------------*/
int main(int argc, char **argv)
{
if(argc != 2){
fprintf(stderr,"Usage: %s <ip>",argv[0]);
exit(1);
}
/*init sock*/
int sock_fd,clisock_fd;
struct sockaddr_in sin,cin;
init_sock(&sock_fd,&sin,argv[1]);
/*init pthread lock*/
pthread_mutex_init(&mutex,NULL);
/*init message*/
int qid;
struct message msg;
qid = init_msg(&msg);
/*cooking thread*/
#if WORK
pthread_t cook_thread;
if(pthread_create(&cook_thread,NULL,cook_fun,(void*)0) != 0)
handle_error("pthread_create");
#endif
/*worker thread*/
pthread_t worker_thread;
if(pthread_create(&worker_thread,NULL,work_fun,(void*)0) != 0)
handle_error("pthread_create");
/*init sem*/
sem_init(&sem,0,0);
/*table init database*/
table_init();
/*open db only one time*/
int rc;
if((rc = sqlite3_open("foodmenu.db",&db))){
perror("sqlite3_open");
sqlite3_close(db);
exit(1);
}
/*------------select-----------------------*/
/*init list*/
struct kool_list mylist;
struct kool_list *tmp;
struct list_head *pos, *q;
INIT_LIST_HEAD(&mylist.list);
int maxfd;
fd_set readfds;
int rv;
struct timeval tv;
pthread_t thread[THREADNUM] = {'\0'};
while(1){
maxfd = 0;
FD_ZERO(&readfds);
FD_SET(sock_fd,&readfds);
maxfd = sock_fd;
/*input the list number to readfds*/
if(!list_empty(&mylist.list)){
list_for_each_safe (pos, q, &mylist.list) {
tmp = list_entry (pos, struct kool_list, list);
FD_SET(tmp->from,&readfds);
if(maxfd < tmp->from)
maxfd = tmp->from;
}
}
tv.tv_sec = 5;
tv.tv_usec = 0;
if((rv = select(maxfd+1,&readfds,NULL,NULL,&tv)) <0)
handle_error("select");
if(rv == 0){
printf("time out\n");
continue;
}else{
/*sock_fd can read*/
if(FD_ISSET(sock_fd,&readfds)){
socklen_t len = sizeof(cin);
bzero(&cin,sizeof(cin));
if((clisock_fd = accept(sock_fd,(struct sockaddr*)&cin,&len)) < 0)
handle_error("accept");
/*add clisock_fd to list*/
tmp = (struct kool_list *) malloc (sizeof (struct kool_list));
tmp->from = clisock_fd;
list_add(&(tmp->list),&(mylist.list));
#if DEBUG
printf("client_IP:%s\n",inet_ntoa(cin.sin_addr));
#endif
}
/*clisock_fd can read*/
if(!list_empty(&mylist.list)){
list_for_each_safe (pos, q, &mylist.list) {
tmp = list_entry (pos, struct kool_list, list);
#if DEBUG
printf ("into read module to= %d from= %d\n", tmp->to, tmp->from);
#endif
if(FD_ISSET(tmp->from,&readfds)){
#if DEBUG
printf ("FD_ISSET success to= %d from= %d\n", tmp->to, tmp->from);
#endif
/*read from the clients*/
char buf[BUFSIZ];
int ret;
bzero(buf,BUFSIZ);
if((ret = read(tmp->from,buf,BUFSIZ)) < 0)
handle_error("read");
if(ret == 0){
/*delete the clisock_fd from list*/
list_del (pos);
close(tmp->from);
free (tmp);
#if DEBUG
printf("one cli is offline\n");
#endif
}
else{
cli_fd = tmp->from;
if(pthread_create(&thread[tmp->from - 3],NULL,fun,(void*)buf) != 0)
handle_error("pthread_create");
/*waiting for new thread runing successfull*/
sem_wait(&sem);
}
}
}
}
}
}
/*ending things*/
pthread_mutex_destroy(&mutex);
sem_destroy(&sem);
return 0;
}
json.c
#include "server.h"
/*analysis json*/
void char_to_json(char *buf,struct json_object *json)
{
}
/*conding json*/
void json_to_char(struct json_object *json,char *buf_fun)
{
}
sqlite3.c
#include "server.h"
void init_sql(void)
{
sqlite3 *db = NULL;
char *errmsg = 0;
int rc;
if((rc = sqlite3_open("foodmenu.db",&db))){
perror("sqlite3_open");
sqlite3_close(db);
exit(1);
}
else printf("hello,you are succeed!\n");
char *sql = "create table fdmenu(id1 integer primary key,varities text,foodname text,prices int);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(1,'甜品类','蛋糕',50);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(2,'甜品类','南瓜饼',60);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(3,'甜品类','糯米丸子',40);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(4,'火锅类','狗肉',88);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(5,'火锅类','羊肉',99);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(6,'火锅类','牛肉',98);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(7,'炒菜类','酸辣土豆丝',30);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(8,'炒菜类','青椒炒肉',40);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(9,'炒菜类','小白菜',25);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(10,'凉拌类','凉拌黄瓜',20);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(11,'凉拌类','花菜',22);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(12,'凉拌类','豆皮',25);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(13,'汤类','紫菜蛋汤',26);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(14,'汤类','排骨汤',50);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(15,'汤类','三鲜汤',33);";
sqlite3_exec(db,sql,0,0,&errmsg);
int nrow = 0;
int ncolumn = 0;
char **result;
//sql = "select * from fdmenu where id2=2";
int re;
re=sqlite3_get_table(db,"select * from fdmenu where varities like '汤类' ",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
perror("sqlite3_get_table");
sqlite3_close(db);
exit(1);
}
int i =0;
printf("row:%d\tcolumn:%d\n",nrow,ncolumn);
printf("\nThe result of querying is :\n");
#if 1
for(i=0;i<(nrow+1)*ncolumn;i++){
if((i+1)%5 != 0){
printf("%s\t",result[i]);
}
else
printf("%s\n",result[i]);}
#endif
sqlite3_free_table(result);
#ifndef _DEBUG_
printf("errmsg=%s\n",errmsg);
#endif
sqlite3_close(db);
}
table.c
#include "server.h"
#if 0
int main(void)
{
//char *sql = "select * from tbmenu;";
char *cust_name = "tablename";
cust(3,cust_name);
return 0;
}
#endif
/*create one table
* tb_id: == the id of desk the cli choose
* cust_name: == cli_id*/
void cust(int tb_id,char *cust_name)
{
char *errmsg = 0;
int rc,re;
int nrow,ncolumn;
char **result;
/*
if ((rc=sqlite3_open("foodmenu.db",&db)) == SQLITE_OK)
printf("welcome to you!\n");
else{
printf("falied to open!\n");
sqlite3_close(db);
exit(1);
}
*/
/*cond int :
* can be return of goods
* 0 : can't
* 1 : can*/
/*
char sql[BUFSIZ];
sprintf(sql,"create table %s(tb_id1 integer primary key,cust_name1 text,fd_id int,fd_name text,prices int,cond int );",cust_name);
sqlite3_exec(db,sql,0,0,&errmsg);
bzero(sql,sizeof(BUFSIZ));
sprintf(sql,"insert into %s values(%d,'%s',0,NULL,0,0);",cust_name,tb_id,cust_name);
sqlite3_exec(db,sql,0,0,&errmsg);
sprintf(sql,"update tbmenu set condition = 1 where id1 = %d;",tb_id);
sqlite3_exec(db,sql,0,0,&errmsg);
*/
char sql[BUFSIZ];
sprintf(sql,"create table %s(id1 integer primary key,tb_id1 int,cust_name1 text,fd_id int,fd_name text,prices int,cond int );",cust_name);
sqlite3_exec(db,sql,0,0,&errmsg);
bzero(sql,sizeof(BUFSIZ));
sprintf(sql,"insert into %s values(0,%d,'%s',0,0,0,0);",cust_name,tb_id,cust_name);
#if DEBUG
printf("%s\n",sql);
#endif
sqlite3_exec(db,sql,0,0,&errmsg);
sprintf(sql,"update tbmenu set condition = 1 where id1 = %d;",tb_id);
sqlite3_exec(db,sql,0,0,&errmsg);
}
/*insert one record to a table
* the table must be create by cust() function*/
void insert_cust(char *cust_name,int fd_id, char *fd_name, int prices)
{
char *errmsg = 0;
int rc;
/*
if ((rc=sqlite3_open("foodmenu.db",&db)) == SQLITE_OK)
printf("welcome to you!\n");
else{
printf("falied to open!\n");
sqlite3_close(db);
exit(1);
}
*/
char sql[BUFSIZ];
bzero(sql,sizeof(BUFSIZ));
sprintf(sql,"insert into %s values(0,0,0,%d,'%s',%d,0);",cust_name,fd_id,fd_name,prices);
sqlite3_exec(db,sql,0,0,&errmsg);
}
void add(int fd_id,char *cust_name)//实现加菜功能
{
char *errmsg = 0;
int rc;
if((rc = sqlite3_open("foodmenu.db",&db) != SQLITE_OK)){
printf("failed to open foodmenu.db!\n");
sqlite3_close(db);
exit(1);
}
char sql[BUFSIZ];
sprintf(sql,"insert into %s(fd_id,fd_name,prices) select id1,foodname,prices from fdmenu where id1 = %d;",cust_name,fd_id);
sqlite3_exec(db,sql,0,0,&errmsg);
sprintf(sql,"update %s set cond = 0 where fd_id = %d;",cust_name,fd_id);
sqlite3_exec(db,sql,0,0,&errmsg);
}
void update_cust(char *cust_name)
{
char *errmsg = 0;
char sql[BUFSIZ];
sprintf(sql,"update %s set cond = 1 where cust_name1 like '%s';",cust_name,cust_name);
sqlite3_exec(db,sql,0,0,&errmsg);
//select cond from 表名 where cust_name1 like 用户名
//返回值是cond 整个列的一维数组 **result
}
void cust_delete(char *cust_name_delete)
{
char *errmsg = 0;
char sql[BUFSIZ];
int re;
char **result;
int nrow = 0;
int ncolumn = 0;
int tb_id=0;
/*
sprintf(sql,"select tb_id1 from %s where cust_name1 like '%s';",cust_name_delete,cust_name_delete);
re=sqlite3_get_table(db,sql,&result,&nrow,&ncolumn,&errmsg);
int tb_id = atoi(result[0]);
printf("table id ==%d\n",tb_id);
sprintf(sql,"update tbmenu set condition = 0 where id1 = %d;",tb_id);
sqlite3_exec(db,sql,0,0,&errmsg);
*/
sprintf(sql,"update tbmenu set condition = 0 where id1 = (select tb_id1 from %s where cust_name1 like '%s');",cust_name_delete,cust_name_delete);
sqlite3_exec(db,sql,0,0,&errmsg);
//sprintf(sql,"delete from %s;",cust_name_delete);
sprintf(sql,"drop table %s;",cust_name_delete);
sqlite3_exec(db,sql,0,0,&errmsg);
}
/*init database
* create foodmenu
* create two table on it*/
void table_init(void)
{
//sqlite3 *db = NULL;
char *errmsg = 0;
int rc;
if((rc = sqlite3_open("foodmenu.db",&db)))
{
perror("sqlite3_open");
sqlite3_close(db);
exit(1);
}
char *sql = "create table tbmenu(id1 integer primary key,varities text,site text,condition int);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(1,'四人座','一楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(2,'四人座','一楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(3,'四人座','一楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(4,'六人座','一楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(5,'六人座','一楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(6,'六人座','一楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(7,'二人座','二楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(8,'二人座','二楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(9,'十人座','二楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "insert into tbmenu values(10,'十人座','二楼',0);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "create table fdmenu(id1 integer primary key,varities text,foodname text,prices int);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(1,'甜品类','蛋糕',50);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(2,'甜品类','南瓜饼',60);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(3,'甜品类','糯米丸子',40);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(4,'火锅类','狗肉',88);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(5,'火锅类','羊肉',99);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(6,'火锅类','牛肉',98);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(7,'炒菜类','酸辣土豆丝',30);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(8,'炒菜类','青椒炒肉',40);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(9,'炒菜类','小白菜',25);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(10,'凉拌类','凉拌黄瓜',20);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(11,'凉拌类','花菜',22);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(12,'凉拌类','豆皮',25);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(13,'汤类','紫菜蛋汤',26);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(14,'汤类','排骨汤',50);";
sqlite3_exec(db,sql,0,0,&errmsg);
sql = "INSERT INTO fdmenu VALUES(15,'汤类','三鲜汤',33);";
sqlite3_exec(db,sql,0,0,&errmsg);
sqlite3_close(db);
}
thread.c
#include "server.h"
#define JSNUM 100
/*cli pthread:deal the client data*/
void *fun(void *arg)
{
int cli_fd_t = cli_fd;
char buf_fun[BUFSIZ];
bzero(buf_fun,BUFSIZ);
memcpy(buf_fun,(char *)arg,BUFSIZ);
/*pose sem let main function continue*/
sem_post(&sem);
#if DEBUG
printf("thread original data :---------------------------------\n%s\n",buf_fun);
printf("strlen of buf_fun :---------------------------------%d\n",strlen(buf_fun));
#endif
//if(strncmp(buf_fun,"\n",1) == 0)
// pthread_exit(0);
if(strlen(buf_fun) <= 9)
pthread_exit(0);
/*decording json*/
json_object *jiebao, *jiebao_cmd, *jiebao_flag;
jiebao= json_tokener_parse(buf_fun);
const char *pstr;
jiebao_cmd=json_object_array_get_idx(jiebao,0);
jiebao_flag=json_object_object_get(jiebao_cmd,"fla");
pstr =json_object_get_string(jiebao_flag);
int int_pstr = atoi(pstr);
switch(int_pstr){
#if DEBUG
printf("pstr == %s\n",pstr);
#endif
/*search for seat*/
case 11:
{
int re;
char **result;
int nrow = 0;
int ncolumn = 0;
char *errmsg;
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
//pthread_mutex_unlock(&mutex);
/*search db*/
re=sqlite3_get_table(db,"select * from tbmenu",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
//exit(-1);
}
pthread_mutex_unlock(&mutex);
int x = 0,y = 0,index = 0;
index = ncolumn;
/*pakage json*/
struct json_object *my_json[nrow];
for( x=0; x<nrow; x++){
my_json[x]=json_object_new_object();
}
for( x=0; x<nrow; x++){
for( y=0; y<ncolumn; y++){
//printf("%s\t",result[index++]);
json_object_object_add(my_json[x],result[y],json_object_new_string(result[index++]));
}
}
sqlite3_free_table(result);
struct json_object *json_shuzu;
json_shuzu=json_object_new_array();
for( x=0; x<nrow; x++){
json_object_array_add(json_shuzu,my_json[x]);
}
const char * buf_cst =json_object_to_json_string(json_shuzu);
write(cli_fd_t,buf_cst,strlen(buf_cst));
#if DEBUG
printf("return seat json:--------------------------------\n%s\n",buf_cst);
#endif
}break;
/*choose one table*/
case 12:
{
int json_length = json_object_array_length(jiebao);
if(json_length != 2){
char *buf_no= "NO";
//write(cli_fd_t,buf_no,strlen(buf_no));
//break;
pthread_exit(0);
}
else {
char *buf_ok="OK";
//write(cli_fd_t,buf_ok,strlen(buf_ok));
}
json_object *json_seat,*json_seat_tmp;
json_seat = json_object_array_get_idx(jiebao,1);
int tb_id;
char cust_name[30];
const char *ppstr;
json_seat_tmp = json_object_object_get(json_seat,"id1");
ppstr =json_object_get_string(json_seat_tmp);
tb_id = atoi(ppstr);
sprintf(cust_name,"cli_id_%d",cli_fd_t);
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
cust(tb_id,cust_name);
pthread_mutex_unlock(&mutex);
#if DEBUG
printf("booking seat OK!--------------------------------------\n");
#endif
}break;
/*search for food*/
case 21:
{
int re;
char **result;
int nrow = 0;
int ncolumn = 0;
char *errmsg;
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
/*search db*/
re=sqlite3_get_table(db,"select * from fdmenu",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
exit(-1);
}
pthread_mutex_unlock(&mutex);
int x = 0,y = 0,index = 0;
index = ncolumn;
/*pakage json*/
struct json_object *my_json[nrow];
for( x=0; x<nrow; x++){
my_json[x]=json_object_new_object();
}
for( x=0; x<nrow; x++){
for( y=0; y<ncolumn; y++){
//printf("%s\t",result[index++]);
json_object_object_add(my_json[x],result[y],json_object_new_string(result[index++]));
}
}
sqlite3_free_table(result);
struct json_object *json_shuzu;
json_shuzu=json_object_new_array();
for( x=0; x<nrow; x++){
json_object_array_add(json_shuzu,my_json[x]);
}
const char * buf_cst =json_object_to_json_string(json_shuzu);
write(cli_fd_t,buf_cst,strlen(buf_cst));
#if DEBUG
printf("send food table to client:------------------------------------\n%s\n",buf_cst);
#endif
}break;
/*add food*/
case 23:;
/*hand up the food tab*/
case 22:
{
int json_length = json_object_array_length(jiebao);
if(json_length == 1){
char *buf_no= "NO";
//write(cli_fd_t,buf_no,strlen(buf_no));
//break;
pthread_exit(0);
}
else {
char *buf_ok="OK";
//write(cli_fd_t,buf_ok,strlen(buf_ok));
if(int_pstr == 22)
total_client++;
}
json_object *json_fd[json_length],*json_fd_tmp[3];
int i;
const char *ptmp[3];
char cust_name22[30];
sprintf(cust_name22,"cli_id_%d",cli_fd_t);
//char tmpchar[20];
for(i = 1; i < json_length; i++){
json_fd[i]= json_object_array_get_idx(jiebao,i);
json_fd_tmp[0] = json_object_object_get(json_fd[i],"id1");//fd_id
json_fd_tmp[1] = json_object_object_get(json_fd[i],"foodname");//fd_name
json_fd_tmp[2] = json_object_object_get(json_fd[i],"prices");//prices
int n;
for(n = 0; n < 3; n++){
ptmp[n] = json_object_get_string(json_fd_tmp[n]);
}
//bzero(tmpchar,20);
//strcpy(tmpchar,ptmp[1]);
//insert_cust(cust_name22, atoi(ptmp[0]),tmpchar,atoi(ptmp[2]));
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
add(atoi(ptmp[0]),cust_name22);
pthread_mutex_unlock(&mutex);
}
struct message msg;
int pid;
pid = init_msg(&msg);
msg.msg_type = 1;
strncpy(msg.msg_text,cust_name22,strlen(cust_name22));
if(msgsnd(pid, &msg, strlen(msg.msg_text),0) == -1)
handle_error("msgsnd");
#if DEBUG
printf("got food table from client.----------------------------------\n");
printf("it is waiting to be cook.----------------------------------\n");
#endif
}break;
/*ask for faster*/
case 31:
{
int re;
char **result;
int nrow = 0;
int ncolumn = 0;
char *errmsg;
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
/*search db*/
re=sqlite3_get_table(db,"select condition from tbmenu where condition = 1",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
exit(-1);
}
pthread_mutex_unlock(&mutex);
sqlite3_free_table(result);
#if DEBUG
printf("get asking :%d pepeo---\n",nrow);
#endif
struct message msg;
int pid;
pid = init_msg(&msg);
msg.msg_type = 2;
bzero(msg.msg_text,BUFSIZ);
char buf[100];
bzero(buf,100);
sprintf(buf,"%d",nrow);
strncpy(msg.msg_text,buf,strlen(buf));
#if DEBUG
printf("msgsnd contain %s\n", msg.msg_text);
#endif
if(msgsnd(pid, &msg, strlen(msg.msg_text),0) == -1)
handle_error("msgsnd");
#if DEBUG
printf("msgsnd ok\n");
#endif
}break;
/*apply for money*/
case 41:
{
#if DEBUG
printf("come into 41: \n");
#endif
int json_length = json_object_array_length(jiebao);
if(json_length != 2){
char *buf_no= "NO";
//write(cli_fd_t,buf_no,strlen(buf_no));
break;
}
#if DEBUG
printf("not break here: \n");
#endif
json_object *json_moy,*json_moy_tmp;
json_moy_tmp = json_object_array_get_idx(jiebao,1);
json_moy = json_object_object_get(json_moy_tmp,"prices");
char cust_name31[30];
sprintf(cust_name31,"cli_id_%d",cli_fd_t);
const char *moy_tmp = json_object_get_string(json_moy);
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
insert_cust(cust_name31, 0,NULL,atoi(moy_tmp));//total money
total_money += atoi(moy_tmp);
#if DEBUG
printf("money is :%s\n",moy_tmp);
printf("%d\n",total_money);
#endif
pthread_mutex_unlock(&mutex);
#if DEBUG
printf("client apply for money.---------------------------------------\n");
#endif
}break;
/*client off line or have applied the money*/
case 51:
{
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
char cust_name_delete[30];
sprintf(cust_name_delete,"cli_id_%d",cli_fd_t);//delete the table of a client
cust_delete(cust_name_delete);
if(strlen(buf_cli) > (BUFSIZ-60))
bzero(buf_cli,BUFSIZ);
sprintf(buf_cli+strlen(buf_cli),"\n--------client %s apply for money----------\n",cust_name_delete);
pthread_mutex_unlock(&mutex);
}break;
default:break;
}
pthread_exit(0);
}
/*cook pthread*/
void *cook_fun(void *arg)
{
struct message msg;
int pid;
int rvmsg;
int rvm;
int i;
pid = init_msg(&msg);
bzero(buf_cook,BUFSIZ);
sprintf(buf_cook,"*******************************************************\n**********************cooker state*********************\n*********************waiting for cooking***************\n*******************************************************\n");
while(1){
/*waiting to cook*/
if((rvmsg = msgrcv(pid, (void*)&msg, BUFSIZ, 1, IPC_NOWAIT)) <= 0){
//continue;
}
else if(rvmsg > 0)
{
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
update_cust(msg.msg_text);
pthread_mutex_unlock(&mutex);
bzero(buf_cook,BUFSIZ);
sprintf(buf_cook,"*******************************************************\n**********************cooker state*********************\n*********************begin to cooking******************\n*******************************************************\n");
for(i = 0; i< 10; i++){
sleep(1);
/*check if there has client urging*/
if((rvm = msgrcv(pid, (void*)&msg, BUFSIZ, 2, IPC_NOWAIT)) <= 0){
//continue;
}
/*has client urging*/
else if(rvm > 0)
{
char buf_ala[BUFSIZ];
bzero(buf_ala,BUFSIZ);
sprintf(buf_ala,"\ncome on, good cooker...\n");
strncpy(buf_cook+strlen(buf_cook),buf_ala,strlen(buf_ala));
}
}
bzero(buf_cook,BUFSIZ);
sprintf(buf_cook,"*******************************************************\n***************client %3s's food is done**********\n*********************And waiting for cooking***********\n*******************************************************\n",msg.msg_text);
sleep(2);
bzero(msg.msg_text,BUFSIZ);
}
}
pthread_exit(0);
}
work.c
#include "server.h"
#define WELCOME 0
#define WORK 1
#define ENDING 2
#define STDIN 0
void display_detail(char **result,int nrow,int ncolumn)
{
system("clear");
int x = 0,y = 0,index = 0;
index = ncolumn;
/*pakage json*/
struct json_object *my_json[nrow];
for( x=0; x<ncolumn; x++){
printf("%s\t",result[x]);
}
printf("\n");
for( x=0; x<nrow; x++){
for( y=0; y<ncolumn; y++){
printf("%s\t",result[index++]);
}
printf("\n");
}
printf("\n");
printf("%s",buf_cook);
printf("%s",buf_cli);
}
void displey_normal(int nrow)
{
system("clear");
printf("-------------------------------------------------------\n");
printf("------total clients today:%6d-----------------------\n",total_client);
printf("------total money:%6d-------------------------------\n",total_money);
printf("------waiting people:%6d----------------------------\n",nrow);
printf("------click (Enter Key) to show waiting detail---------\n");
printf("------click (p Key + Enter Key) to show protocol-------\n");
printf("-------------------------------------------------------\n\n");
printf("%s",buf_cook);
printf("%s",buf_cli);
}
void display_wel(void)
{
system("clear");
printf("-------------------------------------------------\n");
printf("------------- Welcome to work -------------\n");
printf("-------------Happy working Happy day-------------\n");
printf("-------------------------------------------------\n");
}
void display_protocol()
{
system("clear");
printf("\
------------------server protocol----------------------\n\
all data is using json to package----------------------\n\
get [{'fla':'cmd'}], server do as the cmd--------------\n\
cmd == 11 : query seat---------------------------------\n\
cmd == 12 : choose seat--------------------------------\n\
cmd == 21 : query food tab-----------------------------\n\
cmd == 22 : hand up the food tab-----------------------\n\
cmd == 23 : add food to food tab-----------------------\n\
cmd == 31 : urging for faster--------------------------\n\
cmd == 41 : apply for meney----------------------------\n\
cmd == 51 : off line soon------------------------------\n\
-------------------------------------------------------\n\
click Enter to show waiting detail---------------------\n");
}
void display_wrk(void)
{
int re;
char **result;
int nrow = 0;
int ncolumn = 0;
char *errmsg;
char cust_name[100];
int i ;
struct timeval tv;
char buf[BUFSIZ];
fd_set readfd;
int re_se;
int itime = 0,ptime=0;
while(1){
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&readfd);
FD_SET(STDIN, &readfd);
if((re_se = select(STDIN+ 1,&readfd,NULL,NULL,&tv)) == -1){
printf("select error\n");
}
else if(re_se == 0&&itime ==0&&ptime==0){
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
re=sqlite3_get_table(db,"select condition from tbmenu where condition = 1",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
exit(-1);
}
pthread_mutex_unlock(&mutex);
sqlite3_free_table(result);
displey_normal(nrow);
}
else if(FD_ISSET(STDIN,&readfd)){
fgets(buf,BUFSIZ,stdin);
if(!strncmp(buf,"\n",1)){
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
re=sqlite3_get_table(db,"select * from tbmenu",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
}
pthread_mutex_unlock(&mutex);
sqlite3_free_table(result);
display_detail(result,nrow,ncolumn);
itime = 2;
ptime = 0;
}
else if(!strncmp(buf,"p\n",2))
{
display_protocol();
itime = 0;
ptime = 10;
}
}
if(itime!=0){
if(pthread_mutex_lock(&mutex)){
printf("database lock failed!\n");
pthread_exit(NULL);
}
re=sqlite3_get_table(db,"select * from tbmenu",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
}
pthread_mutex_unlock(&mutex);
sqlite3_free_table(result);
display_detail(result,nrow,ncolumn);
itime--;
}
if(ptime!=0){
ptime--;
display_protocol();
}
/*get data*/
/*
re=sqlite3_get_table(db,"select * from tbmenu",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
}
sqlite3_free_table(result);
display_detail(result,nrow,ncolumn);
re=sqlite3_get_table(db,"select condition from tbmenu where condition = 1",&result,&nrow,&ncolumn,&errmsg);
if(re != SQLITE_OK){
printf("%s\n",errmsg);
exit(-1);
}
sqlite3_free_table(result);
displey_normal(nrow);
*/
}
}
void display_end(void)
{
printf("-------------------------------------------------\n");
printf("------------------Thanks for work----------------\n");
printf("-----------------Have a good night---------------\n");
printf("-------------------------------------------------\n");
}
void display(int worksds)
{
switch(worksds){
case WELCOME:display_wel();break;
case WORK:display_wrk();break;
case ENDING:display_end();break;
}
}
/*worker thread*/
void *work_fun(void *arg)
{
display(WELCOME);
//sleep(1);
display(WORK);
display(ENDING);
pthread_exit(0);
}
Makefile
CC = gcc
SRC = ${wildcard *.c}
OBJS = ${patsubst %.c,%,$(SRC)}
all:$(OBJS)
%:%.c
$(CC) -o $@ $^ init.c sqlite3.c thread.c work.c table.c -lpthread -ljson -lsqlite3
clean:
$(RM) $(OBJS) .*.sw?