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

本文详细介绍了如何使用C++在Linux环境下开发一个基于MongoDB数据库的聊天系统ChatServer,包括MongoDB的安装、配置及与C++的集成方法,提供了一个完整的开发流程和实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


在上面两篇文章连篇标题改为 :用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 = root

Database_Pass= root

## 数据库data  ##

Database_config = ch1_data

Database_data = ch1_data

Database_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

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

到此肯定可以成功的了

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

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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值