游戏协议的解析
通过注册的宏REGISTER_NET_MSG把command加入到map_command中,详见代码:
net_command_manager::register_message
处理的代码
BOOL net_command_manager::handle_message(tag_net_message* p_message_, DWORD dw_message_size_, DWORD dw_param_)
{
tag_command* p_command = map_command.find(p_message_->dw_message_id);
++p_command->dw_disposal_num;
NET_MESSAGE_PROC fp = NULL;
p_command->list_command_fn.reset_iterator();
while(p_command->list_command_fn.find_next(fp))
{
(fp)(p_message_, dw_param_);
}
return TRUE;
}
调用handle_message的地方在哪?
user_mgr g_PlayMgr;
VOID user_mgr::update_session()
在si_login_server.cpp中init启动一个线程函数中
while( !b_terminate_update )
{
g_fpWorldMgr.update();
g_PlayMgr.update();
g_rtSession.Update();
g_PlayMgr.start_send_all_msg();
g_anti_addiction_session.update();
}
//si_world_mgr.cpp:world_mgr g_fpWorldMgr;
//si_login_server.cpp:login_server g_login;
world_mgr::update()
VOID world_mgr::update()
{
si_world* p_world = NULL;
map_world.reset_iterator();
while( map_world.find_next(p_world) )
{
p_world->update();
update_world_state(p_world);
}
}
关于线程数量问题:
8*2 + 2 + 4 + 30 + 1 = 53个线程
INT n_work_thread = (get_tool()->get_cup_num() * st_config.n_cpu_work_thread)
// cpu的核心数*2 + 2
INT n_return = _beginthreadex(NULL, 0, thread_accept, this, 0, NULL);
create_send_thread
create_unauth_heartbeat_thread
create_destroy_thread
如何启动网络线程的
p_net_session = new IOCP;
tstring log_name = create_network_log();
p_net_session->get_log()->create_log(log_name.c_str());
tag_server_config init_param;
init_param.fn_login = fastdelegate::MakeDelegate(this, &user_mgr::login_call_back);
init_param.fn_logout = fastdelegate::MakeDelegate(this, &user_mgr::logout_call_back);
init_param.b_repeat_port = true;
init_param.n_port = n_port;
init_param.n_max_client_num = 20000;
init_param.n_accept_num = 256;
p_net_session->init(init_param);
n_port = p_net_session->get_config()->n_port;
Q:网络模块用的是自己写的iocp还是boost::asio
A:用的是自己写的iocp,boostio没有用到,类的名字不一样,一个叫IOCP新的类叫iocp_server_new![这里写图片描述]
game_server是登录到login_server的过程
首先任何连接上的请求,服务器都接受,这样和服务器建立的连接完毕。
这是game_server开始主动的发送第一个请求。
q:login-server中是如何区分这个user还是game-server那?
A: 用了服务器名字做了验证。名字不对立马踢掉。防止玩家恶意冒充game_sever
tmd, 建立了不同线程,game-server和user连接的端口不一样。
p_session = new few_connect_server;
if( !VALID_POINT(p_session) ) return FALSE;
register_world_msg();
INT n_port = login_server::p_var_config->get_int(_T("port"), _T("zone_session"));
p_session->init(fastdelegate::MakeDelegate(this, &world_mgr::login_call_back),
fastdelegate::MakeDelegate(this, &world_mgr::logout_call_back), n_port);
// 上来的第一个协议certification
玩家登录过程
//! 认证类型
enum E_proof_policy
{
epp_null = -1,
epp_test = 0, // 测试专用
epp_own = 1, // 自己公司验证策略
epp_facebook = 2, // facebook
epp_end = 3
};
注意有两种认证的模式并存,自己的客户端用户名密码玩家的客户端用第三方sdk
客户端发送不同的协议来区分这一点
第一个协议
c ----proof----> S
s ---- proof_result ---->c
INT user::handle_message()
{
if( b_conn_lost_ )
return CON_LOST;
DWORD dw_size = 0;
INT n_un_recved = 0;
LPBYTE p_message = recv_msg(dw_size, n_un_recved);
if( !VALID_POINT(p_message) ) return 0;
tag_net_message* p_cmd = (tag_net_message*)p_message;
NETMSGHANDLER p_handler = player_net_mgr.get_handler(p_cmd, dw_size);
if( NULL != p_handler )
(this->*p_handler)(p_cmd);
return_msg(p_message);
return 0;
}
收到数据的代码:iocp_server.cpp: 353
Q:将游戏协议解析成某一代码在哪里?
get_handle()根据id
收到第一个包后进入第一个验证程序user.cpp:335
如果认证都没有问题进入user_mgr.cpp:539
之后程序进入?
1> stdafx.cpp
1>c:/program files/microsoft sdks/windows/v7.0a/include/objidl.h(11280): error C2061: 语法错误: 标识符“__RPC__out_xcount_part”
1>c:/program files/microsoft sdks/windows/v7.0a/include/objidl.h(11281): error C2059: 语法错误:“)”
1>c:/program files/microsoft sdks/windows/v7.0a/include/objidl.h(11281): fatal error C1903: 无法从以前的错误中恢复;正在停止编译
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
解决方法:
在DX目录下的Rpcsal.h中添加如下预编译指令:
#define __RPC__out_xcount_part(size, length)
#define __RPC__in_xcount(size)
#define __RPC__in_xcount_full(size)
#define __RPC__in_range(min, max)
#define __RPC__inout_xcount(size)