C++图书馆管理系统
kuimzzs 人气:0写了一个小项目,图书馆系统,功能如下:
1,添加书籍
2,删除书籍(可删除还没外借的书籍)
3,读者借书
4,读者还书
5,按书籍登入号查看信息(每一本书的书籍登入号唯一,如有5本相同书名作者的书,那就有5个不同的书籍登入号)
6,查询所有图书信息(可以直接查看到同本书在图书馆中的剩余和借出情况)
7,查看指定读者的借书详情
8,注册新读者
9,查看所有书籍信息(可以详细到每个登入号和此登入号书籍的借阅情况:如谁借的,借阅日期)
采用客户端和服务器模式,服务器端接收客户端,一旦接收到便启用线程,然后相应来自此客户端的不同请求
server端
serverHead.h
#ifndef SERVERHEAD #define SERVERHEAD #include <iostream> #include <string> #include <cstdlib> #include <list> #include <iterator> #include <fstream> #include <cstring> #include <thread> #include<WINSOCK2.H> #include <mysql.h> #pragma comment(lib,"ws2_32.lib") struct infoData { int flag; //各种命令 int borFlag; //借阅情况1表示借出,0表示未出借 char enterName[20]; //书籍登入号,一本份 char bookName[50]; //书籍名 char bookNum[20]; //书编号 char bookWriter[50]; //书作者 int remainBook; //最初设置的库存 char readerName[50]; //借书者 char readerNum[50]; //借书证 char borrowTime[30]; //借书时间 int remain; //库中还剩此书数量 int lend; //从库中借出的此书数量 }; class Book_mysql { public: Book_mysql(); bool connectAndCreate(); //链接创建数据库和表 bool selectWhetherEmpty(); //检测是否为空表 bool testTheBookWhetherExist(const infoData& Data); //判断书籍存在 bool insertTo(infoData & Data); //插入书籍 int deleteFrom(infoData & Data); //删除相应书籍 bool readerBorrowBook(infoData & Data); //读者借书 int readerReturnBook(infoData & Data); //还书 bool whetherSurpass(infoData & Data); //判断是否超过借书上限(上限一本书最多借两本) bool selectBookByEntername(infoData & Data); //通过书籍登入号查询书籍 void displayInformation(infoData & Data, const SOCKET& sClient);//打印(笼统) void showTheReaderBook(infoData & Data, SOCKET & sClient);//打印指定读者借书情况 void DISPLAY(infoData & Data, SOCKET& sClient); //打印(详细) private: char user[30]; //登陆名字 char pswd[10]; //密码 char host[20]; //表示本地数据库 unsigned int port; //端口 MYSQL myCont; MYSQL_RES *result; MYSQL_ROW sql_row; int res; }; class Reader_mysql { public: Reader_mysql(); bool connectAndCreate(); bool testTheReaderWhetherExist(infoData & Data);//检测该读者是否已经存在 void insertTo(infoData & Data); //注册 bool readerBorrowBook(); //借书 bool readerReturnBook(); //还书 private: char user[30]; //登陆名字 char pswd[10]; //密码 char host[20]; //表示本地数据库 unsigned int port; MYSQL myCont; MYSQL_RES *result; MYSQL_ROW sql_row; int res; }; class serverSocket { public: serverSocket(int port); ~serverSocket(); SOCKET serverAccpetSocket();//阻塞accept private: WSADATA wsd; SOCKET sServer; //客户端套接字 用来监听 std::list<SOCKET> listScli; //客户端套接字 用链表来接收,接送一个放一个 SOCKET temp; //用来存放中间值 SOCKADDR_IN addrServ; //服务器地址 }; void addBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql); void deleteBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql); void borrowBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql); void returnBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql); void searchBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql); void displayAllBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql); void DISPLAY(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql); void showTheReaderBook(infoData & Data, SOCKET & sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql); void setNewReader(infoData & Data, const SOCKET & sClient, Reader_mysql & reader_mysql); void clientSocketThreadFunction(SOCKET sClient); #endif
套接字类的实现
serverSocket.cpp
#include "serverHead.h" serverSocket::serverSocket(int port) { //初始化套结字动态库 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { std::cout << "WSAStartup failed!" << std::endl; return; } //开始创建服务端socket //创建套接字 AF_INET:ipv4 SOCK_STREAM:使用tcp sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == sServer) { std::cout << "socket failed!" << std::endl; return; } //服务器套接字地址 addrServ.sin_family = AF_INET;//IPv4 addrServ.sin_port = htons(port);//设置端口 建议大于1024 addrServ.sin_addr.s_addr = INADDR_ANY; //表示接受任何客户端的请求 //绑定套接字 绑定服务端socket 和 端口 int ret = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN)); if (SOCKET_ERROR == ret) { std::cout << "bind failed!" << std::endl; return; } //开始监听 ret = listen(sServer, 10); if (SOCKET_ERROR == ret) { std::cout << "listen failed!" << std::endl; return; } } serverSocket::~serverSocket() { closesocket(sServer); //关闭套接字 WSACleanup(); //释放套接字资源; } SOCKET serverSocket::serverAccpetSocket() { //接受客户端请求 sockaddr_in addrClient; int addrClientlen = sizeof(addrClient); temp = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen); if (INVALID_SOCKET == temp) { std::cout << "accept failed!" << std::endl; return -1; } listScli.push_front(temp); return temp; }
MySQL中书籍表的实现
bookMysql.cpp
#include "serverHead.h" Book_mysql::Book_mysql() { strcpy_s(user, "root"); strcpy_s(pswd, "123456"); strcpy_s(host, "localhost"); port = 3306; mysql_init(&myCont); if (mysql_real_connect(&myCont, host, user, pswd, "mysql", port, NULL, 0))//先链接自带的数据库,以便后面创建专属数据库 { res = mysql_query(&myCont, "create database if not exists zhanghsun"); mysql_query(&myCont, "SET NAMES GBK"); if (res) { std::cout << "创建库失败" << std::endl; system("pause"); exit(-1);; } res = mysql_query(&myCont, "use zhanghsun"); if (res) { std::cout << "use 失败" << std::endl; system("pause"); exit(-1); } char order[1024]; sprintf_s(order, "create table IF NOT EXISTS m_book(书籍登入号 char(10) not null, 书名 char(20) default null, 书编号 char(20) default null, 书作者 char(50) default null, 借阅 int default 0, 读者名 char(20) default '%s', 读者借书号 char(20) default '%s', 借阅时间 char(20) default '%s')", "无", "无", "无"); res = mysql_query(&myCont, order); if (res) { std::cout << "创建表失败" << std::endl; system("pause"); exit(-1); } } else { std::cout << "链接失败" << std::endl; system("pause"); exit(-1); } } //判断指定书籍是否存在 bool Book_mysql::testTheBookWhetherExist(const infoData& Data) { char order[1024]; //检测是否存在该书 sprintf_s(order, "SELECT * FROM m_book WHERE 书名='%s' and 书作者 = '%s'", Data.bookName, Data.bookWriter); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { if (sql_row = mysql_fetch_row(result))//如果查询不为空 { return 1;//已有该书 } } } else { std::cout << "查询失败" << std::endl; system("pause"); exit(-1); } return 0;//没有该书 } //插入书籍操作 bool Book_mysql::insertTo(infoData & Data) { char order[1024]; sprintf_s(order, "insert into m_book (书籍登入号,书名,书编号,书作者) values('%s','%s','%s','%s')", Data.enterName,Data.bookName, Data.bookNum, Data.bookWriter); res = mysql_query(&myCont, order); if (res) { std::cout << "插入失败" << std::endl; system("pause"); exit(-1); } return 1; } //判断表是否为空 bool Book_mysql::selectWhetherEmpty() { char order[1024]; sprintf_s(order, "SELECT * FROM m_book"); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { if (sql_row = mysql_fetch_row(result))//获取具体的数据 { return 0;//表不为空 } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } return 1;//表为空 } //判断该读者要借书籍是否超出上限 bool Book_mysql::whetherSurpass(infoData & Data) { char order[1024]; int num = 0; sprintf_s(order, "select 读者名,读者借书号 from m_book where 书名 = '%s' and 书作者 = '%s'", Data.bookName, Data.bookWriter); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { while (sql_row = mysql_fetch_row(result))//获取具体的数据 { if (strcmp(Data.readerName, sql_row[0]) == 0 && strcmp(Data.readerNum, sql_row[1]) == 0) { ++num; } if (num >= 2) { return 1;//已达上限 } } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } return 0;//没超 } //删除书籍 int Book_mysql::deleteFrom(infoData & Data) { char order[1024]; int flag = 0; sprintf_s(order, "SELECT * FROM m_book WHERE 书名='%s' AND 书作者 = '%s' AND 借阅 = '%d'", Data.bookName, Data.bookWriter, 0); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { while (sql_row = mysql_fetch_row(result))//获取具体的数据 { flag = 1; std::cout << "删除登入号:" << sql_row[0] << std::endl; //根据得到的登入号一一删除 sprintf_s(order, "DELETE FROM m_book WHERE 书籍登入号 = '%s'", sql_row[0]); res = mysql_query(&myCont, order); if (res) { std::cout << "删除failed" << std::endl; system("pause"); exit(-1); } } if (flag == 0) { return -1;//全借出 } else if (flag == 1) { return 1;//删除了相关书籍 } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } } //读者借阅书籍 bool Book_mysql::readerBorrowBook(infoData & Data) { char order[1024]; sprintf_s(order, "SELECT 书籍登入号 FROM m_book WHERE 书名='%s' AND 书作者 = '%s' AND 借阅 = '%d'", Data.bookName, Data.bookWriter, 0); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { if(sql_row = mysql_fetch_row(result))//获取具体的数据 { std::cout << "借的书的登入号:" << sql_row[0] << std::endl; sprintf_s(order, "UPDATE m_book SET 借阅 = '%d',读者名 = '%s',读者借书号 = '%s', 借阅时间 = NOW() WHERE 书籍登入号 = '%s'", 1, Data.readerName,Data.readerNum, sql_row[0]); res = mysql_query(&myCont, order); if (res) { std::cout << "更新failed" << std::endl; system("pause"); exit(-1); } } else { return 0;//书全借光 } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } return 1;//借书成功 } //还书 int Book_mysql::readerReturnBook(infoData & Data) { char order[1024]; sprintf_s(order, "SELECT * FROM m_book WHERE 书籍登入号='%s'", Data.enterName); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { if (sql_row = mysql_fetch_row(result))//获取具体的数据 { std::cout << "登入号:" << sql_row[0] << std::endl; sprintf_s(order, "UPDATE m_book SET 借阅 = 0, 读者名 = '%s', 读者借书号 = '%s', 借阅时间 = '%s' WHERE 书籍登入号 = '%s'","无", "无", "无", Data.enterName); res = mysql_query(&myCont, order); if (res) { std::cout << "更新failed" << std::endl; system("pause"); exit(-1); } } else { return 0;//没找到该登入号 } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } return 1;//成功 } //更具书籍登入号查询书籍信息 bool Book_mysql::selectBookByEntername(infoData & Data) { char order[1024]; int flag = 0; sprintf_s(order, "SELECT * FROM m_book WHERE 书籍登入号='%s'", Data.enterName); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { if(sql_row = mysql_fetch_row(result))//获取具体的数据 { flag = 1; strcpy_s(Data.enterName, sql_row[0]); strcpy_s(Data.bookName, sql_row[1]); strcpy_s(Data.bookNum, sql_row[2]); strcpy_s(Data.bookWriter, sql_row[3]); if (atoi(sql_row[4]) == 1) { Data.borFlag = 1; strcpy_s(Data.readerName, sql_row[5]); strcpy_s(Data.readerNum, sql_row[6]); strcpy_s(Data.borrowTime, sql_row[7]); } else { Data.borFlag = 0; } } if (flag == 0) { return 0;//登入号没找到 } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } return 1; } //笼统打印 void Book_mysql::displayInformation(infoData & Data, const SOCKET& sClient) { char order[1024]; char tempName[30]; char tempWriter[30]; int lend = 0; int remain = 0; sprintf_s(order, "SELECT 书名,书编号,书作者 FROM m_book"); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { while (sql_row = mysql_fetch_row(result))//获取具体的数据 { strcpy_s(Data.bookName, sql_row[0]); strcpy_s(Data.bookNum, sql_row[1]); strcpy_s(Data.bookWriter, sql_row[2]); if (strcmp(Data.bookName, tempName) == 0 && strcmp(Data.bookWriter, tempWriter) == 0)//相同书籍不予计算 { continue; } lend = 0; remain = 0; char _order[1024];//已借书情况 sprintf_s(_order, "SELECT count(*) FROM m_book where 书名= '%s' and 书作者 = '%s' and 借阅 = 1", Data.bookName, Data.bookWriter); res = mysql_query(&myCont, _order); if (!res) { MYSQL_RES *_result = mysql_store_result(&myCont); if (_result) { MYSQL_ROW _sql_row; while (_sql_row = mysql_fetch_row(_result))//获取具体的数据 { lend = atoi(_sql_row[0]); } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } //剩余没借情况 sprintf_s(_order, "SELECT count(*) FROM m_book where 书名= '%s' and 书作者 = '%s' and 借阅 = 0", Data.bookName, Data.bookWriter); res = mysql_query(&myCont, _order); if (!res) { MYSQL_RES *_result = mysql_store_result(&myCont); if (_result) { MYSQL_ROW _sql_row; while (_sql_row = mysql_fetch_row(_result))//获取具体的数据 { remain = atoi(_sql_row[0]); } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } Data.lend = lend; Data.remain = remain; if (strcmp(Data.bookName, tempName) != 0 && strcmp(Data.bookWriter, tempWriter) != 0) { Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); } strcpy_s(tempName, Data.bookName); strcpy_s(tempWriter, Data.bookWriter); } } } else { std::cout << "查询failed" << std::endl; system("pause"); exit(-1); } Data.flag = 1; send(sClient, (char*)&Data, sizeof(Data), 0); } //打印指定读者借书情况 void Book_mysql::showTheReaderBook(infoData & Data, SOCKET & sClient) { char order[1024]; int flag = 0; sprintf_s(order, "select 书籍登入号,书名,书编号,书作者,借阅时间 from m_book where 读者名 = '%s' and 读者借书号 = '%s';", Data.readerName, Data.readerNum); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { while (sql_row = mysql_fetch_row(result))//如果查询不为空 { flag = 1; strcpy_s(Data.enterName, sql_row[0]); strcpy_s(Data.bookName, sql_row[1]); strcpy_s(Data.bookNum, sql_row[2]); strcpy_s(Data.bookWriter, sql_row[3]); strcpy_s(Data.borrowTime, sql_row[4]); Data.flag = 6; send(sClient, (char*)&Data, sizeof(Data), 0); } } } else { std::cout << "查询失败" << std::endl; system("pause"); exit(-1); } if (flag == 0) { Data.flag = 0;//没有借书 send(sClient, (char*)&Data, sizeof(Data), 0); } Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); } //打印(详细) void Book_mysql::DISPLAY(infoData & Data, SOCKET& sClient) { char order[1024]; int flag = 0; int i = 0; sprintf_s(order, "select * from m_book"); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { while (sql_row = mysql_fetch_row(result))//如果查询不为空 { flag = 1; strcpy_s(Data.enterName, sql_row[0]); strcpy_s(Data.bookName, sql_row[1]); strcpy_s(Data.bookNum, sql_row[2]); strcpy_s(Data.bookWriter, sql_row[3]); if (atoi(sql_row[4]) == 1) { Data.borFlag = 1; strcpy_s(Data.readerName, sql_row[5]); strcpy_s(Data.readerNum, sql_row[6]); strcpy_s(Data.borrowTime, sql_row[7]); } else { Data.borFlag = 0; } Data.flag = 6; send(sClient, (char*)&Data, sizeof(Data), 0); } } if (flag == 0)//没有结果 { Data.flag = -2; send(sClient, (char*)&Data, sizeof(Data), 0); } } Data.flag = -1;//打印退出flag send(sClient, (char*)&Data, sizeof(Data), 0); }
MySQL读者表的实现
readerMysql.cpp
#include "serverHead.h" Reader_mysql::Reader_mysql() { strcpy_s(user, "root"); strcpy_s(pswd, "123456"); strcpy_s(host, "localhost"); port = 3306; mysql_init(&myCont); if (mysql_real_connect(&myCont, host, user, pswd, "mysql", port, NULL, 0)) { res = mysql_query(&myCont, "create database if not exists zhanghsun"); mysql_query(&myCont, "SET NAMES GBK"); if (res) { std::cout << "创建库失败" << std::endl; system("pause"); exit(-1); } res = mysql_query(&myCont, "use zhanghsun"); if (res) { std::cout << "use 失败" << std::endl; system("pause"); exit(-1); } char order[1024]; sprintf_s(order, "create table IF NOT EXISTS m_reader(读者名 char(20) default null, 读者借书号 char(20) default null)"); res = mysql_query(&myCont, order); if (res) { std::cout << "创建表failed" << std::endl; system("pause"); exit(-1); } } else { std::cout << "链接失败" << std::endl; system("pause"); exit(-1); } } //判断是否重复注册 bool Reader_mysql::testTheReaderWhetherExist(infoData & Data) { char order[1024]; sprintf_s(order, "select * from m_reader where 读者名 = '%s' and 读者借书号 = '%s'", Data.readerName, Data.readerNum); res = mysql_query(&myCont, order); if (!res) { result = mysql_store_result(&myCont); if (result) { if (sql_row = mysql_fetch_row(result))//如果查询不为空 { return 1;//有该读者 } } } else { std::cout << "查询失败" << std::endl; system("pause"); exit(-1); } return 0;//没有此人 } //插入新读者 void Reader_mysql::insertTo(infoData & Data) { char order[102]; sprintf_s(order, "insert into m_reader (读者名, 读者借书号) values('%s','%s')", Data.readerName, Data.readerNum); res = mysql_query(&myCont, order); if (res) { std::cout << "插入失败" << std::endl; system("pause"); exit(-1); } //else 注册成功 }
服务器端总实现
server.cpp
#include "serverHead.h" //增加书籍 void addBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql) { std::cout << "客户端 " << sClient << " 正在录入书籍 !" << std::endl; if (book_mysql.testTheBookWhetherExist(Data))//数据库中判断该书是否已经存在 { std::cout << "客户端" << sClient << " 添加书籍重复已退回" << std::endl; Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return; } //按库存随机每本书的登入号并插入 srand((unsigned)time(NULL));//通过时间来随机登入号 for (int i = 0; i < Data.remainBook; i++) { int x = rand() % 1000; _itoa_s(x, Data.enterName, 10); book_mysql.insertTo(Data);//在数据库中插入 } Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); std::cout << "客户端 " << sClient << " 录入书籍成功 !" << std::endl; } //删除书籍 void deleteBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql) { std::cout << "客户端 " << sClient << " 正在删除书籍" << std::endl; int flag = 0; if (!(book_mysql.testTheBookWhetherExist(Data)))//首先判断该书是否存在 { std::cout << "没有该书" << std::endl; Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return; } //删除 switch (book_mysql.deleteFrom(Data)) { case -1: Data.flag = -2; send(sClient, (char*)&Data, sizeof(Data), 0); std::cout << "该书全部出借,无法进行删除" << std::endl; break; case 1: Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); std::cout << "已删除此书的所有未出借书籍" << std::endl; break; } } //借阅书籍 void borrowBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql) { std::cout << "客户端 " << sClient << " 正在借阅书籍" << std::endl; //判断该读者是否存在 switch (reader_mysql.testTheReaderWhetherExist(Data)) { case 0:Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return;//没有找到该读者,直接return case 1:Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); break;//找到该读者,继续操作 } recv(sClient, (char*)&Data, sizeof(Data), 0); if (book_mysql.selectWhetherEmpty()) { std::cout << "未录入任何书籍" << std::endl; Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return; } if (!(book_mysql.testTheBookWhetherExist(Data))) { Data.flag = -2; std::cout << "没有这本书" << std::endl; send(sClient, (char*)&Data, sizeof(Data), 0); return; } //判断是否多借 if (!(book_mysql.whetherSurpass(Data))) { switch (book_mysql.readerBorrowBook(Data)) { case 1:Data.flag = 0; break;//借书成功 case 0:Data.flag = -3; break;//书全借光 } } else { Data.flag = -4;//借此书已达上限 } send(sClient, (char*)&Data, sizeof(Data), 0); } //归还书籍 void returnBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql, Reader_mysql & reader_mysql) { std::cout << "客户端 " << sClient << " 正在归还书籍" << std::endl; showTheReaderBook(Data, sClient, book_mysql, reader_mysql); recv(sClient, (char*)&Data, sizeof(Data), 0); switch (book_mysql.readerReturnBook(Data)) { case 0:std::cout << "没有找到该登入号" << std::endl; Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); break; case 1:std::cout << "还书成功" << std::endl; Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); break; } } //通过登入号搜索书籍 void searchBook(infoData& Data, const SOCKET& sClient, Book_mysql & book_mysql) { std::cout << "客户端 " << sClient << " 正在通过登入号搜索书籍" << std::endl; switch(book_mysql.selectBookByEntername(Data)) { case 1:send(sClient, (char*)&Data, sizeof(Data), 0);return; case 0:Data.flag = 3; send(sClient, (char*)&Data, sizeof(Data), 0); return; } } //打印书籍(笼统打印,不打印登入号) void displayAllBook(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql) { std::cout << "客户端 " << sClient << " 正在打印书籍(概括)" << std::endl; if (book_mysql.selectWhetherEmpty()) { std::cout << "还没有录入书籍" << std::endl; Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return; } book_mysql.displayInformation(Data, sClient); } //打印每一本书籍的信息(打印每一本书的详细信息) void DISPLAY(infoData& Data, SOCKET& sClient, Book_mysql & book_mysql) { std::cout << "客户端 " << sClient << " 正在打印全部书籍信息" << std::endl; book_mysql.DISPLAY(Data, sClient); } //打印指定读者的借书情况 void showTheReaderBook(infoData & Data, SOCKET & sClient, Book_mysql & book_mysql,Reader_mysql & reader_mysql) { std::cout << "客户端 " << sClient << " 正在打印指定读者的借书情况" << std::endl; switch (reader_mysql.testTheReaderWhetherExist(Data)) { case 0:Data.flag = -1; send(sClient, (char*)&Data, sizeof(Data), 0); return;//没有找到该读者,直接return case 1:Data.flag = 0; send(sClient, (char*)&Data, sizeof(Data), 0); break;//找到该读者,继续操作 } book_mysql.showTheReaderBook(Data, sClient); } //注册新的读者 void setNewReader(infoData & Data, const SOCKET & sClient, Reader_mysql & reader_mysql) { std::cout << "客户端 " << sClient << " 正在注册新读者" << std::endl; switch (reader_mysql.testTheReaderWhetherExist(Data)) { case 1:Data.flag = -1; break;//已有该读者 case 0:Data.flag = 1; reader_mysql.insertTo(Data); break;//注册成功 } send(sClient, (char*)&Data, sizeof(Data), 0); } //线程 void clientSocketThreadFunction(SOCKET sClient) { Book_mysql book_mysql; Reader_mysql reader_mysql; //对客户端的数据进行解析 while (true) { infoData Data; int ret = recv(sClient, (char*)&Data, sizeof(Data), 0); if (SOCKET_ERROR == ret) { std::cout << sClient << "可能下线" << std::endl; return; } int flag = 0; switch (Data.flag)//错误:控制传输跳过的实例化,方法,加{} { //增加书籍 case 1:addBook(Data, sClient, book_mysql); break; //删除书籍 case 2:deleteBook(Data, sClient, book_mysql); break; //借书 case 3:borrowBook(Data, sClient, book_mysql, reader_mysql); break; //还书 case 4:returnBook(Data, sClient, book_mysql, reader_mysql); break; //搜索借书者 case 5: searchBook(Data, sClient, book_mysql); break; //浏览所有书籍信息 case 6: displayAllBook(Data, sClient, book_mysql); break; //查看登入读者的借书情况 case 7:showTheReaderBook(Data, sClient,book_mysql, reader_mysql); break; //注册 case 8:setNewReader(Data, sClient,reader_mysql); break; //退出flag case 9: flag = 1; break; //所有书被借情况一览表 case -10:DISPLAY(Data, sClient, book_mysql); break; default:std::cout << "输入错误 请重新输入:" << std::endl; } if (flag == 1) { std::cout << "客户端 " << sClient << " 下线" << std::endl; break; } } } int main(int argc, char* argv[]) { serverSocket mySocket(8888); while (1) { SOCKET sClient = mySocket.serverAccpetSocket(); if (sClient == -1) { continue; } else { std::cout << "接收到一个客户端 :" << sClient << std::endl; } std::thread t1(clientSocketThreadFunction, sClient);//启用线程 t1.detach(); } return 0; }
client
头文件
clientHead.h
#ifndef CLIENTHEAH #define CLIENTHEAH #include <WINSOCK2.H> #include <iostream> #include <string> #include <thread> using namespace std; #pragma comment(lib, "ws2_32.lib") struct infoData { int flag; //各种命令 int borflag; //借阅情况1表示借出,0表示未出借 char enter_name[20]; //书籍登入号,一本份 char book_name[50]; //书籍名 char book_num[20]; //书编号 char book_writer[50]; //书作者 int remain_book; //最初设置的库存 char reader_name[50]; //借书者 char reader_num[50]; //借书证 char borrow_time[30]; //借书时间 int remain; //库中还剩此书数量 int lend; //从库中借出的此书数量 }; class clientSocket { public: clientSocket(string ipAdress, short port); ~clientSocket(); bool connectToServer(); void receiveData(infoData & data); void sendData(infoData & data); private: WSADATA wsd; //WSADATA变量 SOCKET sClient; //客户端套接字 SOCKADDR_IN servAddr; //服务器地址 int ret; //返回值 }; void menu(); void tapAnyKeyNext(); int addBook(infoData & Data, clientSocket & mySocket); int displayAllbook(infoData Data, clientSocket & mySocket); int deleteBook(infoData & Data, clientSocket & mySocket); int borrowBook(infoData & Data, clientSocket & mySocket); int returnBook(infoData & Data, clientSocket & mySocket); int searchBook(infoData & Data, clientSocket & mySocket); int showTheReaderBook(infoData & Data, clientSocket & mySocket); int setNewReader(infoData & Data, clientSocket & mySocket); void DISPLAY(infoData & Data, clientSocket & mySocket); #endif
套接字类的实现
mySocket.cpp
#include "clientHead.h" clientSocket::clientSocket(string ipAdress, short port) { //初始化套结字动态库 if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { cout << "WSAStartup failed!" << endl; return; } //创建套接字 sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == sClient) { cout << "socket failed!" << endl; return; } servAddr.sin_family = AF_INET; //如果编译通不过 属性 c++ 常规 sdl 改成否 servAddr.sin_addr.s_addr = inet_addr(ipAdress.c_str());//设置服务端地址 这里表示本机 servAddr.sin_port = htons(port); int nServAddlen = sizeof(servAddr); } bool clientSocket::connectToServer() { //连接服务器 ret = connect(sClient, (LPSOCKADDR)&servAddr, sizeof(servAddr)); if (SOCKET_ERROR == ret) { cout << "connect failed!" << endl; system("pause"); return false; } //成功建立连接 可以开始通信了 return true; } void clientSocket::sendData(infoData & Data) { //向服务器发送数据 ret = send(sClient, (char*)&Data, sizeof(Data), 0); if (SOCKET_ERROR == ret) { cout << "send failed!" << endl; return; } } void clientSocket::receiveData(infoData & Data) { // 接收服务器端的数据 recv(sClient, (char*)&Data, sizeof(Data), 0); /*if (ret < 0) { cout << "recv failed" << endl; return; }*/ } clientSocket::~clientSocket() { closesocket(sClient); //关闭套接字 WSACleanup(); //释放套接字资源 }
客户端总实现
client
#include "clientHead.h" void menu() { cout << "*****************************" << endl; cout << endl; cout << "1.录入书籍"<<endl; cout << "2.删除书籍" << endl; cout << "3.借书" << endl; cout << "4.还书" << endl; cout << "5.按书籍登入号查看信息" <<endl; cout << "6.查询所有图书信息" << endl; cout << "7.查看你的借书详情" << endl; cout << "8.注册" << endl; cout << "9.退出" << endl; cout << "-10.查看所有书籍信息" << endl; cout << endl; cout << "*****************************" << endl; } //增加书籍 int addBook(infoData & Data, clientSocket & mySocket) { Data.flag = 1; cout << "开始录入书籍 !" << endl; cout << "输入书名:"; cin >> Data.book_name; cout << "输入书编号:"; cin >> Data.book_num; cout << "输入书作者:"; cin >> Data.book_writer; cout << "输入书库存:"; cin >> Data.remain_book; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == -1) { cout << "已有此书,请勿重复添加" << endl; } if (Data.flag == 0) { cout << "添加成功" << endl; } cout << "是否继续增加书籍操作? 1 : 0 "; while (1) { int x; cin >> x; switch (x) { case 0:return 0;//退出 case 1:return 1;//继续 default:cout << "输入错误 请重新输入:"; } } } //删除书籍 int deleteBook(infoData & Data, clientSocket & mySocket) { if (displayAllbook(Data, mySocket)) { tapAnyKeyNext(); return 0; } cout << "已经外借的那本无法删除" << endl; cout << "输入书名:"; cin >> Data.book_name; cout << "输入作者:"; cin >> Data.book_writer; Data.flag = 2; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == -1) { cout << "没有该书" << endl; } else if (Data.flag == -2) { cout << "该书全部出借,无法进行删除" << endl; } else if (Data.flag == 0) { cout << "删除成功" << endl; } cout << "是否继续删除书籍操作? 1 : 0 "; while (1) { int x; cin >> x; switch (x) { case 0:return 0;//退出 case 1:return 1;//继续 default:cout << "输入错误 请重新输入:"; } } } //借书 int borrowBook(infoData & Data, clientSocket & mySocket) { Data.flag = 3; cout << "输入你的姓名:" << endl; cin >> Data.reader_name; cout << "输入你的借书号:" << endl; cin >> Data.reader_num; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == -1) { cout << "没有找到该读者,是否重新输入?1:2" << endl; char ch[10]; cin >> ch; int x = atoi(ch); switch (x) { case 1:return 1; break; case 2:return 0; break; } } else if (Data.flag == 0) { cout << "登入成功" << endl; } cout << "输入书籍名:"; cin >> Data.book_name; cout << "输入书作者:"; cin >> Data.book_writer; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == 0) { cout << "借书成功" << endl; } else if (Data.flag == -1) { cout << "未录入任何书籍" << endl; } else if (Data.flag == -2) { cout << "没有这本书" << endl; } else if (Data.flag == -3) { cout << "该书已借光" << endl; } else if (Data.flag == -4) { cout << "借此书此书已达上限" << endl; } cout << "是否继续借书操作? 1 : 0 "; while (true) { while (1) { int x; cin >> x; switch (x) { case 0:return 0;//退出 case 1:return 1;//继续 default:cout << "输入错误 请重新输入:"; } } } } //还书 int returnBook(infoData & Data, clientSocket & mySocket) { Data.flag = 4; cout << "输入你的姓名:" << endl; cin >> Data.reader_name; cout << "输入你的借书号:" << endl; cin >> Data.reader_num; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == -1) { cout << "没有找到该读者,是否重新输入?1:2" << endl; char ch[10]; cin >> ch; int x = atoi(ch); switch (x) { case 1:return 1; break; case 2:return 0; break; } } else if (Data.flag == 0) { cout << "登入成功" << endl; } cout << "您所借书如下:" << endl; cout << endl; mySocket.receiveData(Data); if (Data.flag == 0) { cout << endl; std::cout << "你没有借书" << std::endl; cout << endl; return 1; } while (Data.flag == 6) { cout << "登入号 :" << Data.enter_name << endl; cout << "书籍名 :" << Data.book_name << endl; cout << "书籍号 :" << Data.book_num << endl; cout << "作者名 : " << Data.book_writer << endl; cout << "借阅时间 :" << Data.borrow_time << endl; cout << endl; mySocket.receiveData(Data); } cout << "输入登入号还书:" << endl; cin >> Data.enter_name; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == -1) { cout << "没有查询到该登入号" << endl; } else if (Data.flag == 0) { cout << "还书成功" << endl; } cout << "是否继续还书操作? 1 : 0 "; while (true) { while (1) { int x; cin >> x; switch (x) { case 0:return 0;//退出 case 1:return 1;//继续 default:cout << "输入错误 请重新输入:"; } } } } //打印(笼统) int displayAllbook(infoData Data, clientSocket & mySocket) { Data.flag = 6; mySocket.sendData(Data); cout << endl; while (true) { mySocket.receiveData(Data); if (Data.flag == -1) { cout << "没有录入书籍" << endl; return -1; } else if (Data.flag == 1) { break; } else if (Data.flag == 0) { cout << "书籍名 :" << Data.book_name << endl; cout << "书籍号 :" << Data.book_num << endl; cout << "作者名 :" << Data.book_writer << endl; cout << "还剩余 :" << Data.remain << " 本" << endl; cout << "已借出 :" << Data.lend <<" 本"<< endl; cout << endl; } } return 0; } //通过书籍登入号查找书籍信息 int searchBook(infoData & Data, clientSocket & mySocket) { Data.flag = 5; cout << "请输入书籍登入号" << endl; cin >> Data.enter_name; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == 3) { cout << "没有这个登入号" << endl; tapAnyKeyNext(); return 0; } cout << endl; cout << "查询结果如下" << endl; cout << endl; cout << "登入号 :" << Data.enter_name << endl; cout << "书籍名 :" << Data.book_name << endl; cout << "书籍号 :" << Data.book_num << endl; cout << "作者名 : " << Data.book_writer << endl; if (Data.borflag == 1) { cout << "**该书已被借**" << endl; cout << "借书者 :" << Data.reader_name << endl; cout << "借书证 :" << Data.reader_num << endl; } else if (Data.borflag == 0) { cout << "**该书没被借**" << endl; } cout << endl; cout << "查询完成" << endl; cout << "是否继续查询操作? 1 : 0 "; while (true) { while (1) { int x; cin >> x; switch (x) { case 0:return 0;//退出 case 1:return 1;//继续 default:cout << "输入错误 请重新输入:"; } } } } //查看指定读者借书情况 int showTheReaderBook(infoData & Data, clientSocket & mySocket) { Data.flag = 7; cout << "输入你的姓名:" << endl; cin >> Data.reader_name; cout << "输入你的借书号:" << endl; cin >> Data.reader_num; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == -1) { cout << "没有找到该读者,是否重新输入?1:2" << endl; char ch[10]; cin >> ch; int x = atoi(ch); switch (x) { case 1:return 1; break; case 2:return 0; break; } } else if (Data.flag == 0) { cout << "登入成功" << endl; } mySocket.receiveData(Data); if (Data.flag == 0) { cout << "你还没借书" << endl; } else { cout << endl; cout << "查询结果如下" << endl; cout << endl; while (Data.flag == 6) { cout << "登入号 :" << Data.enter_name << endl; cout << "书籍名 :" << Data.book_name << endl; cout << "书籍号 :" << Data.book_num << endl; cout << "作者名 : " << Data.book_writer << endl; cout << "借书时间 :" << Data.borrow_time << endl; cout << endl; mySocket.receiveData(Data); } } cout << "以上是您所有的借书情况" << endl; cout << "是否继续此查询操作? 1 : 0 "; while (true) { while (1) { int x; cin >> x; switch (x) { case 0:return 0;//退出 case 1:return 1;//继续 default:cout << "输入错误 请重新输入:"; } } } } //创建新读者 int setNewReader(infoData & Data, clientSocket & mySocket) { Data.flag = 8; cout << "输入你的姓名:" << endl; cin >> Data.reader_name; cout << "输入你的借书号:" << endl; cin >> Data.reader_num; mySocket.sendData(Data); mySocket.receiveData(Data); if (Data.flag == 1) { cout << "注册成功" << endl; tapAnyKeyNext(); return 0; } else if (Data.flag == -1) { cout << "名字借书号重复,是否重新输入?1:2" << endl; char ch[10]; cin >> ch; int x = atoi(ch); switch (x) { case 1:return 1; break; case 2:return 0; break; } } } //遍历每一本书的详情信息 void DISPLAY(infoData & Data, clientSocket & mySocket) { Data.flag = -10; int i = 0; mySocket.sendData(Data); cout << endl; while (true) { mySocket.receiveData(Data); if (Data.flag == -2) { cout << "没有录入书籍" << endl; tapAnyKeyNext(); return; } if (Data.flag == -1) { break; } /*std::cout << "i = " << i << std::endl; ++i;*/ cout << "登入号 :" << Data.enter_name << endl; cout << "书籍名 :" << Data.book_name << endl; cout << "书籍号 :" << Data.book_num << endl; cout << "作者名 : " << Data.book_writer << endl; if (Data.borflag == 1) { cout << "**该书已被借**" << endl; cout << "借书者 :" << Data.reader_name << endl; cout << "借书证 :" << Data.reader_num << endl; cout << "借阅时间 :" << Data.borrow_time << endl; } else if (Data.borflag == 0) { cout << "**该书没被借**" << endl; } cout << endl; } cout << "查询完成" << endl; cout << endl; tapAnyKeyNext(); } //按任意键退出 void tapAnyKeyNext() { while (1) { cout << "按任意键返回主菜单" << endl; string x; cin >> x; return; } } int main() { clientSocket mySocket("127.0.0.1", 8888); if (!mySocket.connectToServer()) { return 0; } //向服务端发送数据 while (true) { menu(); infoData Data; char ch[20]; cout << "输入操作:"; cin >> ch; int x = atoi(ch); int flag = 0; switch (x) { case 1: { while (1) { if (addBook(Data, mySocket) == 0) { break; } } } break; case 2: { while (1) { if (deleteBook(Data, mySocket) == 0) { break; } } }break; case 3: { while (1) { if (borrowBook(Data, mySocket) == 0) { break; } } }break; case 4: { while (1) { if (returnBook(Data, mySocket) == 0) { break; } } }break; case 5: { while (1) { if (searchBook(Data, mySocket) == 0) { break; } } }break; case 6:displayAllbook(Data, mySocket); tapAnyKeyNext(); break; case 7: { while (1) { if (showTheReaderBook(Data, mySocket) == 0) { break; } } }break; case 8: { while (1) { if (setNewReader(Data, mySocket) == 0) { break; } } }break; case 9:flag = 1; break; case -10:DISPLAY(Data, mySocket); break; default:cout << "输入错误 请重新输入:" << endl; } if (flag == 1) { Data.flag = 9; mySocket.sendData(Data); break; } } WSACleanup(); return 0; }
平台:vs2013
MySQL5.7
综合了MySQL,网络通信,线程等相关知识,看了不少书,但难免有些幼稚的地方请见谅
加载全部内容