西文圖書管理系統(C++、線程、網絡socket、MYSQL)

服務器端:

#include<iostream>
#include<winsock2.h>
#include<stdlib.h>
#include<thread>
#include <mutex>
#include <Windows.h>
#include<mysql.h>


#pragma  comment(lib,"ws2_32.lib")
#pragma comment(lib,"C:\\Program Files\\MySQL\\MySQL Server 5.7\\lib\\libmysql.lib")

struct Library
{
	char  bookName[100];
	char  writerBook[100];
	char  bookId[100];
	char  flag[100];
	char studentName[100];
	char studentNumber[100];
};


void addNewBook(SOCKET & sClient,MYSQL & mycont)
{ 
	using std::cout;
	using std::endl;
	char sql_insert[2048];

	while (1)                       //實現循環添加
	{
		char buffer[1024];
		Library book;
		recv(sClient, buffer, sizeof(buffer), 0);
		if (buffer[0] == 'q')
		{
			cout << "quit" << endl;
			break;
		}
		memcpy(&book, buffer, sizeof(Library));             //將接受的內容轉換爲結構體形式
	sprintf(sql_insert, "insert into mytable(bookname,writerbook,bookid,flag) values(%s,%s,%s,'IN')", book.bookName, book.writerBook,book.bookId);                                                                         
		mysql_query(&mycont, sql_insert);
	}
}

void seeAllBooks(SOCKET & sClient, MYSQL & mycont)
{
	using std::cout;
	using std::endl;
	MYSQL_RES * result;
	MYSQL_ROW sql_col = 0;

	mysql_query(&mycont,"select * from mytable");                //訪問數據庫
	result = mysql_store_result(&mycont);                        //存儲上面命令的結果
	if (result)
	{
		Library book;
		while (sql_col = mysql_fetch_row(result))                //將每一列的結果保存
		{	
			memcpy(book.bookName, sql_col[0], sizeof(book.bookName));
			memcpy(book.writerBook, sql_col[1], sizeof(book.writerBook));
			memcpy(book.bookId, sql_col[2], sizeof(book.bookId));
			memcpy(book.flag, sql_col[3], sizeof(book.flag));
			send(sClient, (char *)&book, sizeof(Library), 0);      //先將要發送的結構體內容整合爲字符串形式再發送
			int t = 1000000;
			while (t > 0)
			{
				t--;
			}
		}
	}
	send(sClient, "q", sizeof("q"), 0);

}

void borrowBook(SOCKET & sClient, MYSQL & mycont)
{
	using std::cout;
	char buffer[1024];
	char mysearch[100];
	Library book;
	MYSQL_RES * result;
	MYSQL_ROW sql_col = 0;

	recv(sClient, buffer, sizeof(buffer), 0);
	memcpy(&book, buffer, sizeof(Library));
	sprintf(mysearch, "select * from mytable where bookname = %s and bookid = %s", book.bookName, book.bookId);        //sprintf實現含變量的命令調用
	mysql_query(&mycont, mysearch);
	if (result = mysql_store_result(&mycont))
	{
		sql_col = mysql_fetch_row(result);
		memcpy(book.bookName, sql_col[0], sizeof(book.bookName));
		memcpy(book.writerBook, sql_col[1], sizeof(book.writerBook));
		memcpy(book.bookId, sql_col[2], sizeof(book.bookId));
		memcpy(book.flag, sql_col[3], sizeof(book.flag));
		send(sClient, (char *)&book, sizeof(Library), 0);

		recv(sClient, buffer, sizeof(buffer), 0);
		memcpy(&book, buffer, sizeof(Library));

		char para[1024];
		sprintf(para,"update mytable set flag = 'OUT',studentName = %s, studentNumber = %s where bookname = %s and bookid = %s", book.studentName, book.studentNumber, book.bookName,book.bookId);
		mysql_query(&mycont, para);
	}
	else
	{
		send(sClient, "q", sizeof("q"), 0);
	}
}

void backBook(SOCKET & sClient, MYSQL & mycont)
{
	using std::cout;
	using std::endl;

	char buffer[1024];
	Library book;
	char mysearch[1024];
	MYSQL_RES * res;


	recv(sClient, buffer, sizeof(buffer), 0);
	memcpy(&book, buffer, sizeof(Library));

	char para[1024];
	sprintf(para, "update mytable set flag = 'IN',studentName = 'NULL',studentNumber = 'NULL' where bookid = %s and studentname = %s",book.bookId, book.studentName);
	mysql_query(&mycont, para);
	Sleep(1);
}

void seeBackBook(SOCKET & sClient, MYSQL & mycont)
{
	using std::cout;
	using std::endl;

	char buffer[1024];
	Library book;
	char mysearch[1024];
	MYSQL_RES * res;
	MYSQL_ROW sql_col;

	sprintf(mysearch,"select * from mytable where flag = 'OUT'");
	mysql_query(&mycont, mysearch);
	res = mysql_store_result(&mycont);
	if (res)
	{
		Library book;
		while (sql_col = mysql_fetch_row(res))
		{
			memcpy(book.bookName, sql_col[0], sizeof(book.bookName));
			memcpy(book.writerBook, sql_col[1], sizeof(book.writerBook));
			memcpy(book.bookId, sql_col[2], sizeof(book.bookId));
			memcpy(book.flag, sql_col[3], sizeof(book.flag));
			memcpy(book.studentName, sql_col[4], sizeof(book.studentName));
			memcpy(book.studentNumber, sql_col[5], sizeof(book.studentNumber));
			send(sClient, (char *)&book, sizeof(Library), 0);
			int t = 1000000;
			while (t > 0)
			{
				t--;
			}
		}
	}
	send(sClient, "q", sizeof("q"), 0);               //終止條件
}

void deleteBook(SOCKET & sClient, MYSQL & mycont)
{
	using std::cout;
	using std::endl;

	char buffer[1024];
	Library book;
	char mysearch[1024];

	recv(sClient, buffer, sizeof(buffer), 0);
	memcpy(&book, buffer, sizeof(Library));

	sprintf(mysearch, "delete from mytable where bookname = %s and bookid = %s", book.bookName, book.bookId);
	mysql_query(&mycont, mysearch);
}



int functions(SOCKET & sClient)
{
	using std::cout;
	using std::cin;
	using std::endl;


	int retVal;
	const int BUF_SIZE = 64;
	char buf[BUF_SIZE];
	char sendBuf[BUF_SIZE];

	const char user[] = "root";
	const char pswd[] = "12345678";
	const char host[] = "localhost";
	const char database[] = "xiwenbase";
	unsigned int port = 3306;
	MYSQL mycont;
	MYSQL_RES * result;
	MYSQL_ROW sql_row;
	int res;
	mysql_init(&mycont);
	if (mysql_real_connect(&mycont, host, user, pswd, database, port, NULL, 0))
	{
		mysql_query(&mycont, "SET NAMES GBK");

		while (1)
		{
			ZeroMemory(buf, BUF_SIZE);
			retVal = recv(sClient, buf, BUF_SIZE, 0);
			if (SOCKET_ERROR == retVal)
			{
				cout << "對方已下線" << endl;
				closesocket(sClient);
				WSACleanup();
				return -1;
			}
			char c;
			c = buf[0];
			if (buf[0] == '0')
			{
				cout << "發送爲空!" << endl;
			}
			switch (c)
			{
			case '1':addNewBook(sClient,mycont); break;
			case '2':seeAllBooks(sClient, mycont); break;
			case '3':borrowBook(sClient, mycont); break;
			case '4':backBook(sClient, mycont); break;
			case '5':seeBackBook(sClient, mycont); break;
			case '6':deleteBook(sClient, mycont); break;
			}
		}
	}
}

int main()
{
	using std::cout;
	using std::cin;
	using std::endl;
	using std::thread;	
	int retVal;
	SOCKET sServer;
	SOCKET sClient;
	WSAData wsd;
	SOCKADDR_IN servaddr;
	SOCKADDR_IN cliaddr;


	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		cout << "startup error!" << endl;
		return -1;
	}
	sServer = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (sServer == INVALID_SOCKET)
	{
		cout << "socket failed!" << endl;
		WSACleanup();
		return -1;
	}
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons((short)4999);
	servaddr.sin_addr.s_addr = INADDR_ANY;

	retVal = bind(sServer, (LPSOCKADDR)&servaddr, sizeof(servaddr));
	if (SOCKET_ERROR == retVal)
	{
		cout << "bind error!" << endl;
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	retVal = listen(sServer, 1024);
	if (SOCKET_ERROR == retVal)
	{
		cout << "listen error!" << endl;
		closesocket(sServer);
		WSACleanup();
		return -1;
	}
	while (1)
	{
		int cliaddrlen = sizeof(cliaddr);
		sClient = accept(sServer, (sockaddr FAR*)&cliaddr, &cliaddrlen);
		if (INVALID_SOCKET == sClient)
		{
			//cout << "accept error!" << endl;
			closesocket(sServer);
			WSACleanup();
			return -1;
		}
		
		thread t1(functions,sClient);                

		t1.detach();
	}
	closesocket(sServer);
	closesocket(sClient);
	WSACleanup();
	return 0;
}



客戶機端:

#include<iostream>
#include <string>
#include<winsock2.h>
#include <iomanip>
#pragma comment(lib,"ws2_32.lib")

using namespace std;

struct Library
{
	char  bookName[100];
	char  writerBook[100];
	char  bookId[100];
	char  flag[100];
	char studentName[100];
	char studentNumber[100];
};

void  show(SOCKET & sServet)
{
	Library book;
	cout << "                  ———————————————————" << endl;
	cout << "                  |      歡迎使用西文圖書室管理系統!  |" << endl;
	cout << "                  |     1、添加新書" << '\t' << "2、查看書庫    |" << endl;
	cout << "                  |     3、借閱圖書" << '\t' << "4、歸還圖書    |" << endl;
	cout << "                  |     5、借書信息" << '\t' << "6、下架廢書    |" << endl;
	cout << "                  ———————————————————" << endl;
	char c;
	cout << "請輸入操作數字:" << endl;
	cin >> c;
	switch (c)
	{
	case '1':
	{
		send(sServet, "1", strlen("1"), 0);
		while (1)
		{			
			cout << "請輸入要添加的書目名稱、作者、書目編號(q退出)" << endl;
			cin >> book.bookName;
			if (book.bookName[0] == 'q')
			{
				send(sServet, "q", sizeof("q"), 0);
				break;
			}
			cin>> book.writerBook >> book.bookId;
			
			memcpy(book.bookName, book.bookName, sizeof(book.bookName));
			memcpy(book.writerBook, book.writerBook, sizeof(book.writerBook));
			memcpy(book.bookId, book.bookId, sizeof(book.bookId));
			send(sServet, (char *)&book, sizeof(Library), 0);
		}
		break;
	}
	case '2':
	{
		char buffer[1024];
		send(sServet, "2", strlen("2"), 0);
		cout << left << setw(6) << "書名" << setw(6) << "作者" << setw(10) << "書目編號" << setw(6) << "借閱狀態" << endl;
		while (1)
		{
			Library book;
			ZeroMemory(buffer, 1024);
			recv(sServet, buffer, sizeof(buffer), 0);
			if (buffer[0] == 'q')
			{
				cout << "顯示完畢!" << endl;
				break;
			}
			memcpy(&book, buffer, sizeof(Library));
			cout << left << setw(6) << book.bookName << setw(6) << book.writerBook << setw(10) << book.bookId << setw(6) << book.flag << endl;
		}
		break;
	}
	case '3':
	{
		char buffer[1024];
		Library book;
		send(sServet, "3", strlen("3"), 0);
		cout << "請輸入你要借閱的書籍的名稱和書目編號:" << endl;
		cin >> book.bookName >> book.bookId;
		memcpy(book.bookName, book.bookName, sizeof(book.bookName));
		memcpy(book.bookId, book.bookId, sizeof(book.bookId));
		send(sServet, (char *)&book, sizeof(Library), 0);
		cout << "1" << endl;

		recv(sServet, buffer, sizeof(buffer), 0);
		if (buffer[0] == 'q')
		{
			cout << "查詢失敗!" << endl;
			break;
		}
		memcpy(&book, buffer, sizeof(Library));
		cout << left << setw(6) << "書名" << setw(6) << "作者" << setw(10) << "書目編號" << setw(6) <<"借閱狀態"<< endl;
		cout << left << setw(6) << book.bookName << setw(6) << book.writerBook << setw(10) << book.bookId << setw(6) << book.flag<<endl;
		if (strcmp(book.flag, "OUT") == 0)
		{
			cout << "對不起,該書已經被借閱!" << endl;
			break;
		}
		else
		{
			cout << "請輸入您的姓名和學號:" << endl;
			cin >> book.studentName >> book.studentNumber;
			memcpy(book.studentName, book.studentName, sizeof(book.studentName));
			memcpy(book.studentNumber, book.studentNumber, sizeof(book.studentNumber));
			send(sServet, (char *)&book, sizeof(Library), 0);
			cout << "借閱成功!" << endl;
		}
		break;
	}
	case '4':
	{

		char buffer[1024];
		send(sServet, "4", strlen("4"), 0);
		Library book;

		cout << "請輸入你要歸還的圖書編號和本人姓名:" << endl;
		cin >> book.bookId >> book.studentName;
		memcpy(book.bookId, book.bookId, sizeof(book.bookId));
		memcpy(book.studentName, book.studentName, sizeof(book.studentName));
		send(sServet, (char *)&book, sizeof(Library), 0);
		cout << "還書成功!歡迎下次使用!" << endl;
		break;
	}
	case '5':
	{
		char buffer[1024];
		send(sServet, "5", strlen("5"), 0);

		cout << left << setw(6) << "書名" << setw(6) << "作者" << setw(10) << "書目編號" << setw(10) << "借閱狀態" << setw(10) << "借書人"<<setw(6) <<"學號"<< endl;
		while (1)
		{
			Library book;
			ZeroMemory(buffer, 1024);
			recv(sServet, buffer, sizeof(buffer), 0);
			if (buffer[0] == 'q')
			{
				cout << "顯示完畢!" << endl;
				break;
			}
			memcpy(&book, buffer, sizeof(Library));
			cout << left << setw(6) << book.bookName << setw(6) << book.writerBook << setw(10) << book.bookId << setw(10) << book.flag << setw(10) << book.studentName<<setw(6) <<book.studentNumber<< endl;
		}
		break;
	}
	case '6':
	{
		send(sServet, "6", strlen("6"), 0);
		cout << "請輸入你要下架的圖書名稱和圖書編號:" << endl;
		cin >> book.bookName >> book.bookId;
		memcpy(book.bookName, book.bookName, sizeof(book.bookName));
		memcpy(book.bookId, book.bookId, sizeof(book.bookId));
		send(sServet, (char *)&book, sizeof(Library), 0);
		cout << "下架成功!" << endl;
		break;
	}
	default:cout << "謝謝使用!" << endl;exit(0);
	}
}

int main()
{
	const int BUF_SIZE = 64;
	WSADATA wsd;
	SOCKET sServer;
	SOCKADDR_IN servaddr;
	char buf[BUF_SIZE];
	char recvBuf[BUF_SIZE];
	int retVal;

	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		cout << "WSAStartup error!" << endl;
		return -1;
	}
	sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sServer)
	{
		cout << "socket error!" << endl;
		WSACleanup();
		return -1;
	}
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	servaddr.sin_port = htons((short)4999);
	int servaddrlen = sizeof(servaddr);

	retVal = connect(sServer, (LPSOCKADDR)&servaddr, servaddrlen);
	if (SOCKET_ERROR == retVal)
	{
		cout << "connect error!" << endl;
		WSACleanup();
		closesocket(sServer);
		return -1;
	}
	while (1)
	{
		show(sServer);
	}
	closesocket(sServer);
	WSACleanup();
	return 0;
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章