寒假项目-酒店综合管理系统

       目前所学的东西依然很有限,难以完成项目,目前只编写了部分代码加以参考。

test.c

#ifndef __TEST_H__
#define SER_PORT 8888                  //服务器端口号
#define SER_IP  "192.168.?.?"      //服务器IP地址
#endif 

//定义一个用于向线程体函数传参的结构体类型
struct MsgInfo
{
    int newfd;
    struct sockaddr_in cin;
};

//定义线程处理函数
void *deal_cli_msg(void *arg)
{

    //解析传进来的参数
    int newfd = ((struct MsgInfo*)arg)->newfd;
    struct sockaddr_in cin = ((struct MsgInfo*)arg)->cin;

    //5、跟客户端进行消息通信
    char buf[128] = "";
    while(1)
    {
        //将数组清空
        bzero(buf, sizeof(buf));

        //读取客户端发来的消息
        //int res = read(newfd, buf, sizeof(buf));
        int res = recv(newfd, buf, sizeof(buf), 0);
        if(res == 0)
        {
            printf("客户端已经下线\n");
            break;
        }
        printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);

        //给客户端发消息
        strcat(buf, "*_*");

        //write(newfd, buf, sizeof(buf));
        send(newfd, buf, sizeof(buf), 0);
        printf("发送成功\n");
    }

    //关闭当前通信的套接字
    close(newfd);

    //退出线程
    pthread_exit(NULL);
}

//注册操作
int do_register()
{
    //追加读写操作,注册内容追加写入
    char access[20];
    char password[20];

	//创建或打开数据库
	sqlite3 *ppDb = NULL;
	if(sqlite3_open("./MYSQL.db", &ppDb) != SQLITE_OK)
    {
        printf("sqlite3_open error,errcode = %d, errmsg = %s\n", sqlite3_errcode(ppDb), sqlite3_errmsg(ppDb));
        return -1;
    }
    printf("sqlite3_open success\n");

    //通过fgets获取终端输入字符串,存入access和password中
    printf("输入账号:");
    fgets(access,sizeof(access),stdin);
    printf("输入密码:");
    fgets(password,sizeof(password),stdin);
    //将字符数组变为字符串
    access[strlen(access)-1]='\0';
    password[strlen(password)-1]='\0';

    char sql[128] = "";
    sprintf(sql, "insert into Users values(%s,%s);",access,password);
    printf("sql = %s\n", sql);
	//向数据库写入数据
	char* errmsg = NULL;
    if(sqlite3_exec(ppDb,sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("sqlite3_exec error: %s\n", errmsg);
        //释放errmsg的空间
        sqlite3_free(errmsg);
        errmsg = NULL;
        return -1;
    }
	
	
	puts("注册成功");
	//关闭数据库
	sqlite3_close(ppDb);

    return 0;
}

int callback(void *arg, int cols, char**value_text, char **value_name)
{


    if((*(int *)arg) == 0)
    {
        //输出表头
        for(int i=0; i

main.c


#define SER_PORT 8888                  //服务器端口号
#define SER_IP  "192.168.?.?"      //服务器IP地址

int main(int argc, const char *argv[])
{
	//创建或打开数据库
	sqlite3 *ppDb = NULL;
	if(sqlite3_open("./MYSQL.db", &ppDb) != SQLITE_OK)
    {
        printf("sqlite3_open error,errcode = %d, errmsg = %s\n", sqlite3_errcode(ppDb), sqlite3_errmsg(ppDb));
        return -1;
    }
    printf("sqlite3_open success\n");
	//创建表格,表名Users
	char sql[128]="create table Users(username char,userpass char)";
	char* errmsg = NULL;
	sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg);
  	
	//关闭数据库
	sqlite3_close(ppDb);
	//登陆
    char num;
    //循环打印选项
    while(1)
    {
        printf("-----1.注册-----\n");
        printf("-----2.登录-----\n");
        printf("-----0.退出-----\n");
        printf("请输入选项:");
        scanf("%c",&num);
        //通过循环吃掉从第二个字符开始的所有垃圾字符
        while(getchar()!='\n');
        switch(num)
        {
            case '1':
                do_register();
                break;
            case '2':
                do_login();
                break;
            case '0':
                exit(EXIT_SUCCESS);
                break;
            default:
                puts("error");
        }
        printf("按回车清屏");
        //吃掉回车前所有垃圾字符
        while(getchar()!='\n');
        system("clear");
    }

    //1、创建用于连接的套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);  
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("sfd = %d\n", sfd);               
    
	//对套接字设置接收超时时间
    struct timeval tv;
    tv.tv_sec = 10;         //10秒
    tv.tv_usec = 0;      
    
	
	//将端口号快速重用函数
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &tv, sizeof(reuse)) == -1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("端口号快速重用成功\n");

    //2、给当前套接字绑定IP地址和端口号
    //2.1填充要绑定的地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family =     AF_INET;        //通信域
    sin.sin_port =         htons(SER_PORT);  //端口号
    sin.sin_addr.s_addr =     inet_addr(SER_IP);    //ip地址

    //2.2 绑定
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success %s %s %d\n", __FILE__, __func__, __LINE__);

    //3、将套接字设置成监听状态
    if(listen(sfd, 128) == -1)
    {
        perror("listen error");
        return -1;
    }
    printf("listen success %s %s %d\n", __FILE__, __func__, __LINE__);

    //4、阻塞等待客户端的链接请求
    //4.1定义容器接收客户端的地址信息
    struct sockaddr_in cin;                  //用于接收地址信息
    socklen_t socklen = sizeof(cin);          //用于接收地址信息的大小

    int newfd = -1;

    pthread_t tid;              //线程id号

    while(1)
    {
        //将程序执行到accept处时,系统会给accept函数预选一个文件描述符,按最小未分配原则
        //4.2 接收客户端的链接
        newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);   
        if(newfd == -1)
        {
            perror("accept error");
            return -1;
        }
        printf("[%s:%d:%d]发来链接请求 %s %s %d\n", \
                inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __FILE__, __func__, __LINE__);

        //定义用于传参的结构体变量
        struct MsgInfo info;
        info.newfd = newfd;
        info.cin = cin;

        //创建分支线程,用于跟新连接的客户端进行交互
        if(pthread_create(&tid, NULL, deal_cli_msg, &info) != 0)
        {
            printf("分支线程创建失败\n");
            return -1;
        }

        //回收线程资源
        pthread_detach(tid);             //将线程分离,后期退出后,由系统回收资源

    }

    //6、关闭套接字
    close(sfd);
    return 0;
}

        以上是本次项目是服务器端的代码,由于遇到了一堆问题,无法得出运行结果,gcc编译阶段都过不了,主要过程是创建数据库,创建表格,表格存储登陆数据,提供登陆/注册选项等,之后创建套接字,端口重用,绑定IP等,使用多线程接收客户端的连接。但是遇到了很多问题。

遇到的问题:

1.采用数据库实现信息存储时,不知道如何查看表中是否存在某种信息,例如希望实现查看用于记录注册的信息,登陆时,想判断表中是否存在该用户名和密码时,不知道怎么判断,网上搜索结果使用的select count(*)......的代码,但是使用时出现了报错信息,并且返回值不知道怎么获取,如果使用

sqlite3_exec(ppDb, sql_password, callback,&count1, &errmsg1);

显然是错误的,目前不知道如何改进。

2.题目中所说的使用Sock编程,所有客户端发送数据采用协议的形式,协议包含两部分:包头+数据,给出了包头等信息,但是我完全没有思路,不知道该怎么搞,客户端发送数据的话直接发送信息就能达到客户端与服务器的通信,进行封装,然后区分数据类型进行不同的操作,这一点不知道如何实现。

3.题目中需要实现多个终端,手持终端发送信息给服务器端,但是不知道如何实现服务器端将接受的信息区分开,选出所点的菜单,然后菜单又是如何不发送给吧台/手持终端的客户端,只发送给多个厨房的客户端?对于这些几乎完全没有思路。

4.正常情况下,服务器的IP地址应该是192.168.?.?,但是连上家里这边的网络之后,使用ifconfig指令得到的结果却是这样的

寒假项目-酒店综合管理系统_第1张图片

似乎无法得到正确的IP地址,不知道是什么原因。

5、厨房客户端,设置每桌订单的状态,分三个状态,初始状态为等待,其次正在准备中,第三个已经完成,实现这个的话,思路大致是,向服务器端发送桌号,然后每隔一段时间向服务器发送等待的状态,那么这个状态怎么到准备中的状态?又怎么到已完成的状态?

总结:这次项目对我目前的水平来说太难了,不管是哪一个部分都难以完全实现,日后结果学习希望能有更好的思路。

你可能感兴趣的:(数据库,sql)