在linux下实现简单聊天系统(三)服务器

我们在在一个主线程进行创建监听套接字,创建线程个数个双向管道(用双向管道因为消息发送是全双工的),创建cpu内核个数-1个子线程,利用libevent监听监听套接字和双向管道的一端,接受客户端连接,为客户端选择处理消息的子线程。

在子线程中,我们分别创建三个子线程来分别完成相应的功能。子线程1负责通过sock_pair双向管道进行与主线程的信息交换,用同一个套接字cli_fd可以让用户选择不同模式,这里使用mvc模式控制,使用的是map表,control控制台。

子线程2用 libevent框架,其中双向管道读取主线程发送的客户端fd,绑定客户端fd处理函数,并给主线程回复当前监听个数。

子线程3用户首次登陆就将用户加入到memeached之中,在规定时间内如果再次登陆就可以在memached中的缓存数据进行查找验证,如果查找不到再进入数据库查找。


主线程代码:

pthread.h

#ifndef PTHREAD_H
#define PTHREAD_H
#include
#include
#include
using namespace std;
class pthread
{
public:
	pthread(int sock_fd);
	~pthread();

private:
	int _sock_fd;//管道1端
	struct event_base *_base;//libevent
	map _event_map;//存储事件的map表
	pthread_t _pthread;//线程描述符

	friend void sock_1_cb(int fd,short event,void *arg);
	friend void cli_cb(int fd,short event,void *arg);
	friend void* pth_run(void *);

};


#endif


pthread.cpp

#include
#include
#include
//#include"control.h"
#include"view.h"
#include"pthread.h"
#include
#include 
#include 
#include 
#include
#include

using namespace std;

void sock_1_cb(int fd,short event,void *arg);
void cli_cb(int fd,short event ,void *arg);
//extern  control control_sever;
void *pth_run(void *arg);

pthread::pthread(int sock_1_fd)
{
	int _sock_1_fd = sock_1_fd;
	_base=event_base_new();
	//启动线程
	int res;
	res=pthread_create(&_pthread,NULL,pth_run,this);
	if(res!=0)
	{
		cerr<<"pthread_run move fail\n"<_base,this3->_sock_fd,EV_READ|EV_PERSIST,sock_1_cb,this3);
	if(NULL == listen_event)
	{
		cout<<"event new fail"<_event_map.insert(make_pair(this3->_sock_fd,listen_event));

	//循环监听
	event_base_dispatch(this3->_base);

}


void sock_1_cb(int fd,short event,void *arg)
{//recv -> clien_fd
	
	//将client_fd加入到libevent     client_cb()
	pthread *this4=(pthread *)arg;

	char buf[16] = {0};
	//int cli_fd;
	if(-1 ==recv(fd,buf,15,0))
	{
		cout<<"accept fail"<::iterator it=this4->_event_map.find(cli_fd);
			event_free(it->second);
			this4->_event_map.erase(it);
		}
	}*/
	int cli_fd = atoi(buf);

	//将clifd加入到事件列表
	struct event* cli_event = event_new(this4->_base,cli_fd,EV_READ|EV_PERSIST,cli_cb,this4);
	if(NULL == cli_event)
	{
		cout<<"cli event creat fail"<_event_map.insert(make_pair(cli_fd,cli_event));
    cout<<" 给主线程回复数据 "<_event_map.size());
	send(fd,buff,sizeof(buff),0);
}

void cli_cb(int fd,short event,void *arg)
{
	//recv  ->buff
	pthread* this5 = (pthread *)arg;
    cout<<"1"<::iterator it=this5->_event_map.find(fd);
		event_free(it->second);
	}
	
	 //   control_sever.process(fd,buff);
}


tcpsever.h

#ifndef TCPSEVER_H
#define TCPSEVER_H
#include
#include"pthread.h"
#include
#include
using namespace std;
class arr
{
	public:
		arr(int brr[2])
		{
			crr[0]=brr[0];
			crr[1]=brr[1];
		}
		int crr[2];
};

typedef class tcpsever
{
public:
	tcpsever(char *ip,short port,int pth_num);
	//~tcpsever();
	
	//服务器运行
	void run();
private:
	int _listen_fd;//监听套接字
	int _pth_num;//线程个数
	//vector  _vec_sock;//socket_pair
	struct event_base* _base;//libevent
	vector_socket_pair;//socket pair vector
	vector_pthread;//pthread vector
	map _pth_num_map;//存储线程负载量的map表

	//创建管道
	void create_socket_pair();
	//创建子线程
	void create_pth();

	//监听套接子回调函数
	friend void listen_cb(int fd,short event,void *arg);
	//双向管道0端回调函数
	friend void sock_0_cb(int fd,short event,void *arg);
}Tcpsever,*Ptcpsever;

#endif


tcpsever.cpp
#include
#include
#include
#include
#include
#include
#include
#include"pthread.h"
#include"tcpsever.h"
#include
using namespace std;

void listen_cb(int fd,short event,void* arg)
{
	//接受链接
	cout<<"listen"<::iterator it1 =this2->_pth_num_map.begin();
	map::iterator it2 =this2->_pth_num_map.begin();
	for(;it1 !=this2->_pth_num_map.end();++it1)
	{
		if(it1->second <= it2->second)
		{
			it2 = it1;
		}
	}
		cout<first<<";"<second<send(it2->first,buf,strlen(buf),0))
	{
	    cerr<<"it2 send fail;errno"<::iterator it=this1->_pth_num_map.begin();
	for(;it!=this1->_pth_num_map.end();it++)
	{
	    if(it->first==fd)
		{
			it->second=atoi(buff);
			return;
		}
	}
	cout<<"not find fd\n"<


control.h

#ifndef CONTROL_H
#define CONTROL_H
#include "view.h"
#include 
#include 
#include
using namespace std;

class Control
{
public:
	Control();
	//~Control();
	virtual void process(int fd,char* json);
    map _map;
};
#endif


control.cpp

#include"exit.h"
#include"talk_to_one.h"
#include"list.h"
#include "register.h"
#include "login.h"
#include "public.h"
#include "control.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
using namespace std;

Control::Control()
{
	_map.insert(make_pair(MSG_TYPE_REGISTER, new Register()));
	_map.insert(make_pair(MSG_TYPE_LOGIN, new Login()));
	_map.insert(make_pair(MSG_TYPE_TALK_TO_ONE, new Talk_to_one()));
	//_map.insert(make_pai(MSG_TYPE_TALK_TO_GTOUP,new View_talk_to_group));
	_map.insert(make_pair(MSG_TYPE_GET_LIST, new List()));
	_map.insert(make_pair(MSG_TYPE_EXIT, new Exit()));
}

void Control::process(int fd,char *json)
{
//	char send_json[128] = {0};
//	sprintf(send_json, "%s", json);
	//解析json,获取消息类型
	Json::Value root;
	Json::Reader read;
	if(-1 == read.parse(json, root))
	{
		cerr<<"Control process json prase fail;errno:"<::iterator it = _map.find(type);
	it->second->process(fd, root);
	it->second->response();
	/*	switch(type)
	{
	   case MSG_TYPE_LOGIN:
		   {
			   cout<<"login"<::iterator it=_map.find(type);
		       it->second->process(fd,root);
			   it->second->response();
			   break;
		   }
	   
	   case MSG_TYPE_REGISTER:
		   {
			   map::iterator it=_map.find(type);
		       it->second->process(fd,root);
			   it->second->response();
			   break;
		   }
	  case MSG_TYPE_EXIT:
		   {
			   map::iterator it=_map.find(type);
		       it->second->process(fd,root);
			   it->second->response();
			   break;
		   }
	  case MSG_TYPE_GET_LIST:
		   {
			   map::iterator it=_map.find(type);
		       it->second->process(fd,root);
			   it->second->response();
			   break;
		   }
	  case MSG_TYPE_TALK_TO_ONE:
		   {
			   map::iterator it=_map.find(type);
		       it->second->process(fd,root);
			   it->second->response();
			   break;
		   }
	   default:
		   {
		       cout<<"type error"<::iterator it = _map.find(root["reason_type"].asInt());
	//判断是否找到
	if(it == _map.end())
	{
		Json::Value val;
		val["reaso_type"] = "new Type fail";

		if(-1 == send(fd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0))
		{
			cerr<<"Control process send fail;errno:"<second->process(fd,json);
	it->second->response();
}*/
	}
Control control_sever;





你可能感兴趣的:(linux,项目)