服务器开发—数据库Mongodb及C++驱动安装

来源:互联网 发布:网络教育电大 编辑:程序博客网 时间:2024/05/20 18:17

自己做为屌丝批评下自己,前两往篇文章我写得太烂了,连我自己都不想看,所以接下来的文章,如果写我就要写得让大家明白,不然不写


在上面两篇文章连篇标题改为 :用C++在Linux下开发聊天系统ChatServer

我所介绍的ChatServer采用的是Mongodb数据库

Mongodb是NoSQL类的数据库,目前也是NoSQL数据库最流行的,它的安装很简单,下载、解压即可


下载地址:http://www.mongodb.org/downloads

根据服务器的系统下载相应即可

解压后的文件 很简单,只一个bin目录和几个文件

启动:解压目录/bin/mongod --port 27017 --dbpath 数据存放目录 --auth

这里注意下--auth选项,这个代表是客户端要验证才能操作数据库,刚安装的时候不要该 --auth(还没有建立用户)

默认端口是27017,所以--port也是可以去掉的


第一步:/bin/mongod --dbpath  ./data &


第二步:/bin/mongo 

( 这里可以输入了)

1、要先建立一个管理数据库admin(必须是这个)

use admin

使用use 表示选择或新建一个数据库

2、设置用户密码

db.addUser('user,'pass')

成功后会出现ok之类的提示符

3、验证是否正确

db.auth('user','pass')

返回 1代表成功,0失败

4、然后我们按照上面的步骤建立ch1_config、ch1_data、ch1_log数据库,并要设置验证

5、退出

exit

====================以上建立完了===============================

下面我们来关掉Mongod数据库,再以验证(--auth)的方式启动

先找到mongodb进程

ps -ef|grep mongod

然后kill -9 进程ID 或killall mongod

然后去删除/data/下的mongodb.lock文件(这个很重要,很多人启动不成功都是因为它)

再次启动

/bin/mongod --auth --dbpath ./data & 

===============================================================

这样不报错就代表成功了;好了,下面我来介绍下安装c++ mongodb  driver

下载地址:http://dl.mongodb.org/dl/cxx-driver/

选择mongodb-linux-x86_64-v2.0-latest.tgz下载即可

下载后,在任意目录下解压,这个记录要安装pcre,scons(安装mongodb辅助工具)

下载pcre http://sourceforge.net/projects/pcre/files/pcre/8.00/

    #tar pcre-8.00.tar.gz
    #cd pcre-8.00
    #./configure   
    #make install     pcre完成
5. 下载scons,本例中scons-2.1.0-1.noarch.rpm
 http://sourceforge.net/projects/scons/files/scons/2.1.0/
 #rpm  -ivh scons-2.1.0-1.noarch.rpm   安装完成

安装mongodb driver

解压#tar zxvf mongodb-linux-x86_64-v2.0-latest.tgz

#cd mongodb-linux-x86_64-v2.0

安装mongodb-driver是采用scons该软件辅助安装 的

 # scons --extrapath=/usr/local/(自己的安装目录即可)

安装完成后会出现如下字符

scons: Reading SConscript files ...
Checking for C library boost_thread-mt... yes
Checking for C library boost_filesystem-mt... yes
Checking for C library boost_system-mt... yes
Checking for C library boost_thread-mt... yes
scons: done reading SConscript files.
scons: Building targets ...

File "/usr/bin/scons", line 178, in <module>
g++ -o client/examples/authTest.o -c -O3 -D_SCONS -DMONGO_EXPOSE_MACROS -Imongo client/examples/authTest.cpp
g++ -o mongo/buildinfo.o -c -O3 -D_SCONS -DMONGO_EXPOSE_MACROS -Imongo mongo/buildinfo.cpp
g++ -o mongo/pch.o -c -O3 -D_SCONS -DMONGO_EXPOSE_MACROS -Imongo mongo/pch.cpp
g++ -o mongo/bson/oid.o -c -O3 -D_SCONS -DMONGO_EXPOSE_MACROS -Imongo mongo/bson/oid.cpp

...省略一部分....
g++ -o authTest -Wl,--as-needed -Wl,-zdefs client/examples/authTest.o -L. -lmongoclient -lpthread -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt
.....省略一部分....
mongo/util/net/httpclient.os mongo/util/net/listen.os mongo/util/net/message.os mongo/util/net/message_port.os mongo/util/net/sock.os mongo/util/md5.os -lpthread -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt
g++ -o secondExample -Wl,--as-needed -Wl,-zdefs client/examples/second.o-L. -lmongoclient -lpthread -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt
g++ -o whereExample -Wl,--as-needed -Wl,-zdefs client/examples/whereExample.o -L. -lmongoclient -lpthread -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt
scons: done building targets.

这些信息很用,比如: -L. -lmongoclient -lpthread -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt 

这个是在编译或链接时的参数,如果我们不注意这些信息,到我们去写代码手动或自动编译时就会出现各种神马的错误了,所以先记下来先,

好了,在当前目录下有几个测试文件,如firstExample、authTest,clentTest等,这个可以运行看看,它们是已经编译好的,运行没有什么问题,这里有还个client目录,里面有很多例子,我们可以打开eclispe,将这些例子放进去编译运行一下,这时是eclispe自动编译时,会出现奇怪的报错,下面看下最近我写的一人C++ Mongodb类:

注意下,我用了空间名

Mongodb.h

/* * Mongodb.h * *  Created on: 2012-10-26 *      Author: root */#ifndef MONGODB_H_#define MONGODB_H_#include "mongo/client/dbclient.h"#include "../base/Exception.h"#include "../config/ServerConfig.h"#include "../util/StringFormat.h"namespace consts {using namespace std;using namespace mongo;using namespace config;using namespace util;using namespace base;class Mongodb {public:Mongodb();virtual ~Mongodb();static DBClientConnection conn;static void Init();};} /* namespace consts */#endif /* MONGODB_H_ */


在这里时,首先要告诉大家,要将解压的src/include/mongo文件夹复制到/usr/local/include下,作为引入文件,当然放到系统有include的其他地方也行,如:/usr/include


Mongodb.cpp

/* * Mongodb.cpp * *  Created on: 2012-10-26 *      Author: root */#include "Mongodb.h"namespace consts {DBClientConnection Mongodb::conn;Mongodb::Mongodb() {// TODO Auto-generated constructor stub}Mongodb::~Mongodb() {// TODO Auto-generated destructor stub}void Mongodb::Init() {string errmsg;// 连接if (!conn.connect(ServerConfig::GetDatabaseIp() + ":"+ StringFormat::Int2Str(ServerConfig::GetDatabasePort()),errmsg)) {throw Exception(errmsg);}// 验证if (!conn.auth(ServerConfig::GetDatabaseConfig(),ServerConfig::GetDatabaseUser(), ServerConfig::GetDatabasePass(),errmsg)) {throw Exception(errmsg);}if (!conn.auth(ServerConfig::GetDatabaseData(),ServerConfig::GetDatabaseUser(), ServerConfig::GetDatabasePass(),errmsg)) {throw Exception(errmsg);}if (!conn.auth(ServerConfig::GetDatabaseLog(),ServerConfig::GetDatabaseUser(), ServerConfig::GetDatabasePass(),errmsg)) {throw Exception(errmsg);}}} /* namespace consts */


这里有个抛错类,可以用输入字符串,再return 来代替

这里有个用到ServerConfig类,还在StringFormat,下面我也将这两个类粘代码上来:


StringFormat.h

/* * StringFormat.h * *  Created on: 2012-10-22 *      Author: root */#ifndef STRINGFORMAT_H_#define STRINGFORMAT_H_#include <iostream>#include <string>#include <vector>#include <string.h>#include <sstream>#include <stdlib.h>namespace util {class StringFormat {public:StringFormat();virtual ~StringFormat();static int Str2Int(const std::string s);static std::string Int2Str(const int i);static std::vector<std::string> split(std::string str,std::string pattern);};} /* namespace util */#endif /* STRINGFORMAT_H_ */

StringFormat.cpp

/* * StringFormat.cpp * *  Created on: 2012-10-22 *      Author: root */#include "StringFormat.h"namespace util {StringFormat::StringFormat() {// TODO Auto-generated constructor stub}StringFormat::~StringFormat() {// TODO Auto-generated destructor stub}int StringFormat::Str2Int(const std::string s){return atoi(s.c_str());}std::string StringFormat::Int2Str(int i){std::ostringstream oss;oss << i;return oss.str();}std::vector<std::string> StringFormat::split(std::string str,std::string pattern) {std::string::size_type pos;std::vector<std::string> result;str += pattern;int size = str.size();for (int i = 0; i < size; i++) {pos = str.find(pattern, i);if (pos < size) {std::string s = str.substr(i, pos - i);result.push_back(s);i = pos + pattern.size() - 1;}}return result;}} /* namespace util */

ServerConfig.h

/* * ServerConfig.h * *  Created on: 2012-10-25 *      Author: root */#ifndef SERVERCONFIG_H_#define SERVERCONFIG_H_#include <map>#include <string>#include "../util/StringFormat.h"using namespace std;using namespace util;namespace config {class ServerConfig {public:ServerConfig();virtual ~ServerConfig();static void Init(const std::string filename);static string GetServerIp();static int GetServerPort();static string GetDatabaseIp();static int GetDatabasePort();static string GetDatabaseUser();static string GetDatabasePass();static string GetDatabaseConfig();static string GetDatabaseData();static string GetDatabaseLog();private :static map<string,string> _map;};} /* namespace config */#endif /* SERVERCONFIG_H_ */

ServerConfig.cpp

/* * ServerConfig.cpp * *  Created on: 2012-10-25 *      Author: root */#include "ServerConfig.h"#include "../util/Config.h"namespace config {map<string,string> ServerConfig::_map;ServerConfig::ServerConfig() {// TODO Auto-generated constructor stub}ServerConfig::~ServerConfig() {// TODO Auto-generated destructor stub}void ServerConfig::Init(const std::string filename) {Config::ReadConfig(filename, _map);}string ServerConfig::GetServerIp() {return _map["ServerIp"];}int ServerConfig::GetServerPort(){return StringFormat::Str2Int(_map["ServerPort"]);}string ServerConfig::GetDatabaseIp(){return _map["DatabaseIp"];}int ServerConfig::GetDatabasePort(){return StringFormat::Str2Int(_map["DatabasePort"]);}string ServerConfig::GetDatabaseUser(){return _map["Database_User"];}string ServerConfig::GetDatabasePass(){return _map["Database_Pass"];}string ServerConfig::GetDatabaseConfig(){return _map["Database_config"];}string ServerConfig::GetDatabaseData(){return _map["Database_config"];}string ServerConfig::GetDatabaseLog(){return _map["Database_config"];}} /* namespace config */

这时还有个Config类,这个类主要加载配置文件用,很好用,从其他地方抄的,哈哈,下面作者不是我的名字啊

Config.h

/* * Config.h * *  Created on: 2012-10-24 *      Author: root *//*****************************************************************************   作者:  jasitzhang(张涛)*   日期:  2011-10-2*   目的:  读取配置文件的信息,以map的形式存入*   要求:  配置文件的格式,以#作为行注释,配置的形式是key = value,中间可有空格,也可没有空格*****************************************************************************/#ifndef CONFIG_H_#define CONFIG_H_#define COMMENT_CHAR '#'#include <string>#include <map>using namespace std;namespace util {class Config {public:Config();virtual ~Config();static bool ReadConfig(const string& filename,map<string,string>& m);static void PrintConfig(const map<string,string>& m);static bool IsSpace(char c);static bool IsCommentChar(char c);static void Trim(string& str);static bool AnalyseLine(const string& line,string& key,string& value);};} /* namespace util */#endif /* CONFIG_H_ */

Config.cpp

/* * Config.cpp * *  Created on: 2012-10-24 *      Author: root */#include <fstream>#include <iostream>#include "Config.h"using namespace std;namespace util {Config::Config() {// TODO Auto-generated constructor stub}Config::~Config() {// TODO Auto-generated destructor stub}bool Config::IsSpace(char c) {if (' ' == c || '\t' == c)return true;return false;}bool IsCommentChar(char c) {switch (c) {case COMMENT_CHAR:return true;default:return false;}}void Config::Trim(string& str){if(str.empty()){return ;}int i, start_pos,end_pos;for(i=0;i<str.size();++i){if(!IsSpace(str[i])){break;}}if( i == str.size() ){ // 全部是空白字符串str = "" ;return ;}start_pos = i ;for(i = str.size() - 1 ; i >= 0; --i) {if(!IsSpace(str[i])){break;}}end_pos = i;str = str.substr(start_pos , end_pos -  start_pos + 1);}bool Config::AnalyseLine(const string& line,string & key,string & value){if(line.empty()){return false;}int start_pos = 0, end_pos = line.size() - 1,pos;if((pos = line.find(COMMENT_CHAR))!=-1){if(0 == pos){// 行的第一个字符就是注释字符return false;}end_pos = pos -1;}string new_line = line.substr(start_pos,start_pos + 1 - end_pos);//  // 预处理,删除注释部分if((pos = new_line.find('=')) == -1){return false; // 没有=号}key = new_line.substr(0,pos);value = new_line.substr(pos + 1 ,end_pos + 1 - (pos + 1)) ;Trim(key);if(key.empty()){return false;}Trim(value);return true;}bool Config::ReadConfig(const string& filename,map<string,string> & m){m.clear();ifstream infile(filename.c_str());if(!infile){cout << "file open error " << endl;}string line,key,value;while(getline(infile,line)){if(AnalyseLine(line,key,value)){m[key] = value;}}infile.close();return true;}void Config::PrintConfig(const map<string,string>& m){map<string,string>::const_iterator mite = m.begin();for(; mite != m.end(); ++ mite){cout << mite ->first << "=" << mite->second << endl;}}} /* namespace util */
还有个server.cfg

##=============服务器==================##  服务器IP  ##ServerIp = 192.168.154.131##   服务器端口  ##ServerPort = 8800##=============数据库=================##  数据库IP  ##DatabaseIp = 192.168.154.131##  数据库端口  ##DatabasePort = 27017##Database_User = rootDatabase_Pass= root## 数据库data  ##Database_config = ch1_dataDatabase_data = ch1_dataDatabase_log = ch1_log

几乎所有文件 都贴上去了,那就开始编译吧,但老是报错,这是因为少了某些库,又如自己又加了-lboost_thread等,还是错,这里我们刚才说到要保存编译mongodb driver的编译信息的用处了,哈哈,

好,如果是用eclispe的就要项目的编译选项( c/c++ build -> setting-> *-flag )中追加如下信息

-L. -lmongoclient -lpthread -lboost_thread-mt -lboost_filesystem-mt -lboost_system-mt -lboost_thread-mt

手动编译就要后面直接加上去就行了

到此肯定可以成功的了

谢谢各位的阅读,本人博客年龄尚轻,希望得到各位的指正,谢谢!

=============================================================