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

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

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<cols; i++)
        {
            printf("%-10s", value_name[i]);
        }
        printf("\n");
        *((int *)arg)  = 1;       //更改标识位
    }

    //输出当前记录的信息
    for(int i=0; i<cols; i++)
    {
        printf("%-10s", value_text[i]);
    }
    printf("\n");

    return 0;
}

//登录操作
int do_login()
{
    char access[20];
    char password[20];
    //存入终端输入的账号密码
    printf("输入账号:");
    fgets(access,sizeof(access),stdin);
    printf("输入密码:");
    fgets(password,sizeof(password),stdin);

    access[strlen(access)-1]='\0';
    password[strlen(password)-1]='\0';

	//创建或打开数据库
	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");
    	
		// 查看数剧库是否有这个名字存在
		char sql_access[128]="select count(*) from Users where username=access";
		char sql_password[128]="select count(*) from Users where userpass=password";
		int count1 = 0,count2 = 0;

		char* errmsg1 = NULL;   
		char* errmsg2 = NULL;   
		sqlite3_exec(ppDb, sql_access, callback,&count1, &errmsg1);
		sqlite3_exec(ppDb, sql_password, callback,&count1, &errmsg2);
		if(count1 != 0&& count2!=0)
		{
            puts("登录成功");
        }

	//关闭数据库
	sqlite3_close(ppDb);
    return 0;

}

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指令得到的结果却是这样的

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/390072.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#上位机与三菱PLC的通信03--MC协议之A-1E报文解析

1、MC协议帧 MC协议可以在串口通信&#xff0c;也可以在以太网通信&#xff0c;有A-1E和Qna-3E两种模式&#xff0c;这两种都是三菱PLC通信协议中比较常用的两种&#xff0c;一般我们使用比较多的是以太网通信&#xff0c;对于FX5U系列/Q系列/Qna系列/L系列的PLC&#xff0c;…

糟糕,接口被刷了,怎么办?

前言 在面试时&#xff0c;经常会被问一个问题&#xff1a;如何防止别人恶意刷接口&#xff1f; 这是一个非常有意思的问题&#xff0c;防范措施挺多的。今天这篇文章专门跟大家一起聊聊&#xff0c;希望对你会有所帮助。 1 防火墙 防火墙是网络安全中最基本的安全设备之一&…

Python eval函数

在Python编程中&#xff0c;eval()函数是一个强大且灵活的内置函数&#xff0c;用于动态执行字符串表达式或代码。尽管eval()函数具有强大的功能&#xff0c;但它也带来了一些潜在的安全风险&#xff0c;因此在使用时需要谨慎。本文将深入探讨eval()函数的用法、语法、示例代码…

AI:129-基于深度学习的极端天气事件预警

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

Kibana:如何嵌入 Kibana 仪表板

作者&#xff1a;Carly Richmond 像我这样的前端工程师经常提出的要求是将 Kibana 等来源的现有仪表板嵌入到 JavaScript Web 应用程序中。 这是我必须多次执行的任务&#xff0c;因为我们希望快速部署用户生成的视图或允许用户控制给定的视图。 从我们从精彩的开发者社区收到的…

安装 Windows Server 2019

1.镜像安装 镜像安装:Windows Server 2019 2.安装过程(直接以图的形式呈现) 先选择""我没有产品密钥"",选择桌面体验 选择自定义 设置密码后继续 安装成功

算法——组合数学——二项式定理

杨辉三角是二项式系数的典型应用当 n 较大&#xff0c;且需要取模时&#xff0c;二项式系数有两种计算方法&#xff1a; 一&#xff1a;递推公式&#xff0c;二&#xff1a;逆 方法一&#xff1a;用递推公式计算二项式系数 public class BinomialCoefficient {public static i…

【数据结构】16 二叉树的定义,性质,存储结构(以及先序、后序、中序遍历)

二叉树 一个二叉树是一个有穷的结点集合。 它是由根节点和称为其左子树和右子树的两个不相交的二叉树组成的。 二叉树可具有以下5种形态。 性质 一个二叉树第i层的最大结点数为 2 i − 1 2^{i-1} 2i−1, i ≥ 1 i \geq 1 i≥1 每层最大结点可以对应完美二叉树&#xff08;…

可视化锻炼日记ExerciseDiary

什么是 ExerciseDiary &#xff1f; ExerciseDiary 是带有 GitHub 风格的年度可视化的锻炼日记。 安装 在群晖上以 Docker 方式安装。 在注册表中搜索 exercisediary &#xff0c;选择第一个 aceberg/exercisediary&#xff0c;版本选择 latest。 本文写作时&#xff0c; lat…

互联网时代的文学复兴:中文诗词大数据分析 | 开源日报 No.170

chinese-poetry/chinese-poetry Stars: 45.4k License: MIT 最全的中文诗歌古典文集数据库&#xff0c;包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。数据来源于互联网。该开源项目旨在通过 JSON 格式分发&#xff0c;方便用户开始自己的项目&#xff0c;并借…

从零开始实现一个三维绘图系统

文章目录 框架布局绘图函数源代码 框架 本文的目标是实现一个下图所示的系统&#xff0c;通过指定 x , y , z x,y,z x,y,z的表达式&#xff0c;以实现三维绘图的目的。这个需求其实此前也实现过&#xff0c;见此文&#xff0c;但其内容比较驳杂&#xff0c;并不利于快速实现&a…

VBA中表示单元格样式A1、R1C1和R[1]C[1]之间的区别

《VBA之Excel应用》&#xff08;版权10178983&#xff09;是非常经典的&#xff0c;是我推出的第七套教程&#xff0c;定位于初级&#xff0c;目前是第一版修订。这套教程从简单的录制宏开始讲解&#xff0c;一直到窗体的搭建&#xff0c;内容丰富&#xff0c;实例众多。大家可…

springboot189基于SpringBoot电商平台的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

java-类与对象

一、类与对象 二、快速入门 三、类与对象的区别和联系 四、对象在内存中的存在形式

跟着pink老师前端入门教程-day27

三、变量 &#xff08;一&#xff09;变量概述 1、什么是变量 白话&#xff1a;变量就是一个装东西的盒子 通俗&#xff1a;变量是用于存放数据的容器&#xff0c;通过变量名获取数据&#xff0c;甚至数据可以修改 2、变量在内存中的存储 本质&#xff1a;变量是程序在内存…

原型模式-Prototype Pattern

原文地址:https://jaune162.blog/design-pattern/prototype-pattern/ 引言 在Java中如果我们想要拷贝一个对象应该怎么做?第一种方法是使用 getter和setter方法一个字段一个字段设置。或者使用 BeanUtils.copyProperties() 方法。这种方式不仅能实现相同类型之间对象的拷贝,…

解决vitepress首次加载慢(从40秒到1秒的倔强)

前言&#xff1a;在艰难的博客系统升级之路 这篇博客中我有提到vitepress首次加载非常耗时的问题&#xff0c;之前也在网上搜索时发现也有很多人说这个“问题”&#xff0c;但是在折腾了这么一段时间后&#xff0c;发现这也许本身不是vitepress的问题&#xff0c;而是我的启动方…

「递归算法」:两两交换链表中的节点

一、题目 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出&#xf…

Harris关键点检测原理简介

一、2D Harris 二、 3D Harris Harris关键点检测以及SAC-IA粗配准-CSDN博客

Docker部署Springboot项目

一、把Springboot项目打成jar包 &#xff08;一&#xff09;右键项目文件&#xff0c;点击Open Module Settings &#xff08;二&#xff09;选中Artifacts&#xff0c;点击中间的加号&#xff08;Project Settings->Artifacts->JAR->From modules with dependencies…
最新文章