C++实现简单图书馆管理系统

C++实现简单图书馆管理系统

本文实例为大家分享了C++实现简单图书馆管理系统的具体代码,供大家参考,具体内容如下

写了一个小项目,图书馆系统,功能如下:

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,网络通信,线程等相关知识,看了不少书,但难免有些幼稚的地方请见谅

推荐阅读