bool PasServer::ConnectServer(User &user, unsigned int timeout) { if (time(0) - user._connect_info.last_reconnect_time < user._connect_info.timeval) return false; bool ret = false; if (user._fd != NULL) { OUT_INFO(NULL, 0, NULL, "fd %d close socket", user._fd->_fd); CloseSocket(user._fd); } user._fd = _tcp_handle.connect_nonb(user._ip.c_str(), user._port, timeout); ret = (user._fd != NULL) ? true : false; if (ret) { user._user_state = User::WAITING_RESP; DownConnectReq req; req.header.msg_seq = ntouv32(_proto_parse.get_next_seq()); req.header.access_code = ntouv32(user._access_code); req.verify_code = ntouv32(_verify_code); OUT_INFO(user._ip.c_str(), user._port, user._user_id.c_str(), "Send DownConnectReq,down-link state:CONNECT_WAITING_RESP"); SendCrcData(user._fd, (const char*) &req, sizeof(req)); } else { user._user_state = User::OFF_LINE; } user._last_active_time = time(0); user._login_time = time(0); user._connect_info.last_reconnect_time = time(0); if (user._connect_info.keep_alive == ReConnTimes) user._connect_info.reconnect_times--; return true; }
DepthRegistration *DepthRegistration::New(Method method) { if(method == DEFAULT) { #ifdef DEPTH_REG_OPENCL method = OPENCL; #elif defined DEPTH_REG_CPU method = CPU; #endif } switch(method) { case DEFAULT: OUT_ERROR("No default registration method available!"); break; case CPU: #ifdef DEPTH_REG_CPU OUT_INFO("Using CPU registration method!"); return new DepthRegistrationCPU(); #else OUT_ERROR("CPU registration method not available!"); break; #endif case OPENCL: #ifdef DEPTH_REG_OPENCL OUT_INFO("Using OpenCL registration method!"); return new DepthRegistrationOpenCL(); #else OUT_ERROR("OpenCL registration method not available!"); break; #endif } return NULL; }
bool MsgClient::Init( ISystemEnv *pEnv ) { _pEnv = pEnv ; // 初始化转换环境对象 _convert->initenv( pEnv ) ; // 设置处理MSG用户的回调对象 _pEnv->SetNotify( MSG_USER_TAG , this ) ; char temp[512] = {0} ; // 获取图片的基地址 if ( ! pEnv->GetString( "base_picurl" , temp ) ) { printf( "get picture base url failed\n" ) ; return false ; } _picUrl.SetString( temp ) ; // 加载基本订阅列表路径 if ( pEnv->GetString( "base_dmddir" ,temp ) ) { _dmddir.SetString( temp ) ; OUT_INFO( NULL, 0 , NULL, "Load base dmddir %s", temp ) ; } // 加载用户白名单列表 if ( pEnv->GetString( "user_whitelist", temp ) ) { _whiteLst.LoadList( temp ) ; OUT_INFO( NULL, 0 , NULL, "Load white list macid %s", temp ) ; } int nvalue = 0; int send_thread = 1 ; // 发送线程 if ( pEnv->GetInteger( "http_send_thread" , nvalue ) ) { send_thread = nvalue ; } int recv_thread = 1 ; // 接收线程 if ( pEnv->GetInteger( "http_recv_thread" , nvalue ) ) { recv_thread = nvalue ; } int queue_size = 1000 ; // HTTP请求最大的队列长度 if ( pEnv->GetInteger( "http_queue_size" , nvalue ) ) { queue_size = nvalue ; } // 初始化异步的HTTP图片对象 _httpCall.Init( send_thread, recv_thread, queue_size ) ; // 调置回调对象 _httpCall.SetReponse( this ) ; // 设置分包对象处理分包 setpackspliter( &_packspliter ) ; return true ; }
void NetRunInfo::show() { struct timeval cur_timeval; gettimeofday(&cur_timeval, NULL); //total:%d(updata:%d, online:%d, commret:%d), fail total:%d, current average:%d/s //单位是ms long long timeval = (cur_timeval.tv_sec - _btimeval.tv_sec) * 1000 + ((cur_timeval.tv_usec - _btimeval.tv_usec) / 1000) + 1; long long avg_send_num = _cur_send_num.value() * 1000 / timeval; long long avg_recv_num = _cur_recv_num.value() * 1000 / timeval; long long avg_send_total = _cur_send_total_size.value() * 1000 / timeval; long long avg_recv_total = _cur_recv_total_size.value() * 1000 / timeval; _cur_send_num.reset(); _cur_recv_num.reset(); _cur_send_total_size.reset(); _cur_recv_total_size.reset(); gettimeofday(&_btimeval, NULL); char buffer[256] = { 0 }; snprintf(buffer, sizeof(buffer) - 1, "send(avg:%lld/s flux %s/s, total:%lld, send size:%s), recv(avg:%lld/s flux %s/s, total:%lld, recv size:%s)", avg_send_num, host_size(avg_send_total).c_str(), _send_num.value(), host_size(_send_total_size.value()).c_str(), avg_recv_num, host_size(avg_recv_total).c_str(), _recv_num.value(), host_size(_recv_total_size.value()).c_str()); OUT_INFO(NULL, 0, "net_run_info", buffer); }
void MsgClient::HandleOfflineUsers() { vector<User> vec_users = _online_user.GetOfflineUsers(3*60); for(int i = 0; i < (int)vec_users.size(); i++) { User &user = vec_users[i]; if(user._socket_type == User::TcpClient) { if(user._fd != NULL ) { OUT_WARNING( user._ip.c_str() , user._port , user._user_name.c_str() , "fd %d close socket", user._fd->_fd ); CloseSocket(user._fd); } } else if(user._socket_type == User::TcpConnClient) { if( user._fd != NULL ) { OUT_INFO( user._ip.c_str() , user._port , user._user_name.c_str() ,"conn fd %d close socket", user._fd->_fd ); user.show(); CloseSocket(user._fd); user._fd = NULL; } if ( ConnectServer(user, 10) ) { // 添加列表中。 _online_user.AddUser( user._user_id, user ) ; } else if ( user._connect_info.keep_alive == AlwaysReConn ) { // 添加用户 _online_user.AddUser( user._user_id, user ) ; } } } }
void PasServer::NoopWork() { OUT_INFO( NULL, 0, NULL, "void PasServer::NoopWork()"); while (1) { if (!Check()) break; HandleOnlineUsers(30); if (_login_check->Reload(30 * 3)) { OUT_INFO(NULL, 0, NULL, "Reload config file:%s success", _login_check->get_config_file().c_str()); } sleep(3); } }
void PasServer::HandleOfflineUsers() { vector<User> vec_users = _online_user.GetOfflineUsers(3 * 60); for (int i = 0; i < (int) vec_users.size(); i++) { User user = vec_users[i]; if (user._socket_type == User::TcpClient) { // 移除统计功能的用户 _datastat.Remove(user._access_code); if (user._fd != NULL) { OUT_WARNING( user._ip.c_str(), user._port, user._user_id.c_str(), "HandleOfflineUsers close socket fd %d", user._fd->_fd); CloseSocket(user._fd); } } else if (user._socket_type == User::TcpConnClient) { if (user._fd != NULL) { OUT_WARNING( user._ip.c_str(), user._port, user._user_id.c_str(), "TcpConnClient close socket fd %d", user._fd->_fd); // user.show(); CloseSocket(user._fd); user._fd = NULL; } if (ConnectServer(user, 3)) { //连接成功,重新加到在线列表当中。 if (!_online_user.AddUser(user._user_id, user)) _online_user.SetUser(user._user_id, user); } else if (user._connect_info.keep_alive == AlwaysReConn || user._connect_info.reconnect_times > 0) { _online_user.AddUser(user._user_id, user); } else { if (user._connect_info.reconnect_times <= 0) { // 如果用户是下级平台,应该向下级平台发送从链路断开消息 DownDisconnectInform msg; msg.header.msg_len = ntouv32(sizeof(DownDisconnectInform)); msg.header.access_code = ntouv32(user._access_code); msg.header.msg_seq = ntouv32(_proto_parse.get_next_seq()); msg.header.msg_type = ntouv16(DOWN_DISCONNECT_INFORM); msg.error_code = 0x0; // 原因:从链路断开 char buf[200]; sprintf(buf, "U_%u", user._access_code); // 取主链路fd User main_user = _online_user.GetUserByUserId(buf); if (!main_user._user_id.empty()) { if (SendCrcData(main_user._fd, (const char*) &msg, sizeof(msg))) { OUT_INFO( main_user._ip.c_str(), main_user._port, "pas", "DOWN_DISCONNECT_INFORM"); } else { OUT_ERROR( main_user._ip.c_str(), main_user._port, "pas", "DOWN_DISCONNECT_INFORM"); } } } } } } }
void MsgClient::Stop( void ) { OUT_INFO("Msg",0,"MsgClient","stop"); StopClient() ; _httpcaller.Stop() ; }
void MsgClient::NotifyUser( const _UserInfo &info , int op ) { string key = info.tag + info.code ; User user = _online_user.GetUserByUserId( key ) ; OUT_PRINT( info.ip.c_str(), info.port, key.c_str() , "PasClient operate %d user, username %s, password %s" , op , info.user.c_str(), info.pwd.c_str() ) ; switch( op ){ case USER_ADDED: { ConvertUser( info, user ) ; // 添加新的用户 if ( ! _online_user.AddUser( key, user ) ) { if ( user._fd ) { OUT_INFO( user._ip.c_str(), user._port, user._user_id.c_str() , "MsgClient Add New user close fd %d" , user._fd->_fd ) ; CloseSocket( user._fd ) ; } _online_user.SetUser( key, user ) ; } } break ; case USER_DELED: if ( ! user._user_id.empty() ) { if ( user._fd ) { OUT_INFO( user._ip.c_str(), user._port, user._user_id.c_str() , "MsgClient Delete User fd %d" , user._fd->_fd ) ; CloseSocket( user._fd ) ; } // 删除用户处理 _online_user.DeleteUser( key ) ; } break ; case USER_CHGED: if ( ! user._user_id.empty() ) { // 修改用户数据 ConvertUser( info, user ) ; if ( user._fd ) { OUT_INFO( user._ip.c_str(), user._port, user._user_id.c_str() , "MsgClient Change User close fd %d" , user._fd->_fd ) ; CloseSocket( user._fd ) ; } _online_user.SetUser( key, user ) ; } break ; } }
// 发送关闭连接请求, msgid:UP_DISCONNECT_INFORM,UP_CLOSELINK_INFORM void CPccServer::Close( int accesscode , unsigned short msgid, int reason ) { OUT_PRINT( NULL, 0, NULL, "close accesscode %d down link, msgid %d, reason %d" , accesscode, msgid, reason ) ; char uid[128] = {0}; sprintf( uid, "%d", accesscode ) ; User user = _online_user.GetUserByUserId( uid ) ; if ( user._user_id.empty() ) { return ; } switch( msgid ) { case UP_CLOSELINK_INFORM: // 关闭主从链路 case UP_DISCONNECT_INFORM: // 关闭主链路 { UpDisconnectInform req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_seq = ntouv32( _proto_parse.get_next_seq() ) ; req.header.access_code = ntouv32( accesscode ) ; req.header.msg_type = ntouv16( msgid ) ; req.error_code = reason ; // 发送断连数据 SendCrcData( user._fd, (const char *)&req, sizeof(req) ) ; /** if ( msgid == UP_CLOSELINK_INFORM ) { // 关闭主链路请求处理 _pEnv->GetPasClient()->Close( accesscode ) ; }*/ OUT_INFO( user._ip.c_str(), user._port, user._user_id.c_str(), "Send %s", (msgid == UP_CLOSELINK_INFORM) ? "UP_CLOSELINK_INFORM" : "UP_DISCONNECT_INFORM" ) ; } break ; default: // 断开连接处理 { user._user_state = User::OFF_LINE ; _online_user.SetUser( uid, user ) ; OUT_INFO( user._ip.c_str(), user._port, user._user_id.c_str(), "Close Sublink set user state offline" ) ; } break ; } }
// 纷发登陆用 void MsgClient::SendDemandData( socket_t *sock ) { set<string>::iterator it; // 当前组不空需要处理 if (!_groupsubmgr.IsEmpty()) { string groups; set<string> &temp = _groupsubmgr.GetSubIds(); for (it = temp.begin(); it != temp.end(); ++it) { if (!groups.empty()) { groups += ","; } groups += *it; } string scmd = "DMD 1 {" + groups + "} \r\n"; SendData( sock, scmd.c_str(), scmd.length()); OUT_INFO( sock->_szIp, sock->_port, NULL, "fd %d, Send group cmd %s", sock->_fd, scmd.c_str() ); } // 如果当前MACID不为空也需要处理 if (!_macidsubmgr.IsEmpty()) { string macids; set<string> &temp = _macidsubmgr.GetSubIds(); for (it = temp.begin(); it != temp.end(); ++it) { if (!macids.empty()) { macids += ","; } macids += *it; } string scmd = "ADD 0 {" + macids + "} \r\n"; SendData( sock, scmd.c_str(), scmd.length()); OUT_INFO( sock->_szIp, sock->_port, NULL, "fd %d, Send macid cmd %s", sock->_fd, scmd.c_str() ); } }
void WasServer::on_dis_connection(socket_t *sock) { User user = _online_user.DeleteUser(sock); if (!user._user_id.empty()) { return; } //专门处理底层的链路突然断开的情况,不处理超时和正常流程下的断开情况。 OUT_INFO( sock->_szIp , sock->_port , user._user_id.c_str(), "ENV on_dis_connection fd %d", sock->_fd ) ; _pEnv->GetWasClient()->DelTerminal(user._user_id); }
// 添加到数据包对象 bool CPackMgr::AddPack( DataBuffer &pack, const char *carid, const int msgid, const int index, const int count, const int seq, const char *buf, int len ) { share::Guard g( _mutex ) ; { if ( count <= 0 || index <= 0 ) { OUT_ERROR( NULL, 0, "packmgr" , "msg id %x, add pack car id %s, count %d, index %d error" , msgid, carid, count, index ) ; return false ; } char key[1024] = {0} ; // 这里ID是由手机号以及消息ID和分包数 sprintf( key, "%s-%d-%d-%d" , carid, msgid, count , (seq-index)+1 ) ; CMemFile *p = NULL ; CMapFile::iterator it = _mapPack.find( key ) ; if ( it == _mapPack.end() ) { p = new CMemFile(key) ; if ( p == NULL ) { OUT_ERROR( NULL, 0, "packmgr" , "msg id %x, add pack car id %s, count %d, index %d malloc data faild" , msgid, carid, count, index ) ; return false ; } } else { p = it->second ; // 移除不必要时间索引 p = _queue.erase( p ) ; } // 如果成功将多个数据合成一个数据包则直接从内存删除 if ( p->AddBuffer( pack, index, count, buf, len ) ) { // 打印数据信息 OUT_INFO( NULL, 0, "packmgr" , "msg id %x, build msg pack success", msgid ) ; // 只有不为一个数据长消息才会有索引 if ( it != _mapPack.end() ) { // 从队列中移除 _mapPack.erase( it ) ; } delete p ; return true ; } // 只有第一次添加时才添加到队列中 if ( it == _mapPack.end() ) { _mapPack.insert( pair<string,CMemFile*>( key, p ) ) ; } // 添加时间索引 _queue.push( p ) ; return false ; } }
void TcpClient::on_dis_connection(socket_t *sock) { OUT_INFO( sock->_szIp, sock->_port, "dis", "Recv disconnect fd %d", sock->_fd ); User user = _online_user.GetUserBySocket(sock); if (user._user_id.empty()) { OUT_WARNING(sock->_szIp, sock->_port, "dis", "get user fail, fd %d", sock->_fd); return; } user._fd = NULL; user._user_state = User::OFF_LINE; _online_user.SetUser(user._user_id, user); }
bool MsgClient::Init( ISystemEnv *pEnv ) { _pEnv = pEnv ; // 初始化转换环境对象 _convert->initenv( pEnv ) ; char temp[256] = {0} ; // HTTP的URL的基地址的路径 if ( pEnv->GetString( "base_picurl", temp ) ) { _picUrl = temp ; } // 加载基本订阅列表路径 if ( pEnv->GetString( "base_dmddir" ,temp ) ) { _dmddir.SetString( temp ) ; OUT_INFO( NULL, 0 , NULL, "Load base dmddir %s", temp ) ; } if ( ! pEnv->GetString( "user_filepath" , temp ) ) { printf( "load user file failed\n" ) ; return false ; } int nvalue = 0 , send_thread = 1, recv_thread = 1, queue_size = 1000 ; // 发送线程 if ( pEnv->GetInteger( "http_send_thread" , nvalue ) ) { send_thread = nvalue ; } // 接收线程 if ( pEnv->GetInteger( "http_recv_thread" , nvalue ) ) { recv_thread = nvalue ; } // HTTP请求最大的队列长度 if ( pEnv->GetInteger( "http_queue_size" , nvalue ) ) { queue_size = nvalue ; } // 初始化HTTP的服务 if ( ! _httpcaller.Init( send_thread, recv_thread, queue_size ) ) { OUT_ERROR( NULL, 0, NULL, "init http caller failed" ) ; return false ; } _httpcaller.SetReponse( this ) ; // 设置分包对象 setpackspliter( &_packspliter ) ; return LoadMsgUser( temp ) ; }
void printHelp () { OUT_INFO ("\n2grayEngine -s File.txt -o out.txt"); OUT_INFO ("\n[-s] - silent. No output"); OUT_INFO ("\n[Filename] - File to run"); OUT_INFO ("\n[-0 fileName] - output file. If not specified ouput will"); OUT_INFO ("be printed on console"); OUT_INFO ("\n"); }
void MsgClient::HandleInnerData( socket_t *sock, const char *data, int len) { const char *ip = sock->_szIp; unsigned short port = sock->_port; User user = _online_user.GetUserBySocket( sock ) ; if ( user._user_id.empty() ) { OUT_ERROR( ip, port, NULL, "get fd %d user failed", sock->_fd ) ; return ; } // CAITS 0_0 MACID 0 U_REPT {TYPE:5,18:上下线状态/前置机服务器ID/管道控制服务ID/消息服务器id} string line(data, len); vector<string> vec; if ( !splitvector( line, vec, " ", 6 ) ) { OUT_ERROR( ip, port, user._user_name.c_str() , "fd %d data error: %s", sock->_fd, data ); return; } string macid = vec[2] ; if ( macid.empty() ){ OUT_ERROR( ip, port, user._user_name.c_str(), "fd %d macid empty", sock->_fd ) ; return ; } string vechile ; if ( ! _macid2carnum.GetSession( macid, vechile ) ) { OUT_ERROR( ip, port, user._user_name.c_str(), "fd %d get vechile num by mac id %s failed", macid.c_str() ) ; return ; } string acode ; DataBuffer buf ; // 转换控制指令 if (vec[4] == "D_CTLM") { // 转换控制指令 _convert->convert_ctrl( vec[1], macid , vec[5] , vechile, buf , acode ) ; } else if ( vec[4] == "D_SNDM" ) { OUT_INFO( ip, port, user._user_name.c_str(), "D_SNDM"); //xifengming _convert->convert_sndm( vec[1] , macid, vec[5], vechile, buf, acode ) ; } if ( ! acode.empty() && buf.getLength() > 0 ) { // 下发给PAS对应的接入商 _pEnv->GetPasServer()->HandlePasDown( acode.c_str(), buf.getBuffer(), buf.getLength() ) ; } user._last_active_time = time(NULL); _online_user.SetUser(user._user_id, user); }
// 向MSG上传消息 void MsgClient::HandleUpMsgData( const char *code, const char *data, int len ) { OUT_INFO( NULL, 0, "msg", "HandleUpMsgData %s", data ) ; string userid ; // 从会话中取得发送对象 if ( _session.GetSession( code , userid ) ) { // 如果存在会话处理 User user = _online_user.GetUserByUserId( userid ) ; // 如果当前用户在线 if ( ! user._user_id.empty() && user._user_state == User::ON_LINE ) { SendData( user._fd, data, len ) ; } return ; } SendDataToUser( code , data, len ) ; }
// 保存数据包处理 bool CScpMedia::CScpFileManager::SaveScpFile( int fd, const char *macid, int id, int total, int index, int type, int ftype,int event,int channel, const char * data, int len , const char *gps , MultiDesc *desc ) { share::Guard g( _mutex ) ; { //构建唯一的KEY值 macid ; string key = macid ; key += "_" ; key += uitodecstr(total) ; bool binsert = false ; CScpFile *p = NULL ; MapScpFile::iterator it = _index.find( key ) ; if ( it == _index.end() ) { p = new CScpFile(key.c_str()); // 初始化参数设置 binsert = p->Init( fd, macid, id, total, type, ftype, event, channel, _cur_dir.c_str() , gps ) ; } else { p = it->second ; // 如果第一个包不是第一个到达则需要重新设置文件名 if ( index == 0x01 ) { p->SetParam( fd, macid, id, total, type, ftype, event, channel, _cur_dir.c_str() , gps ) ; } p = _queue.erase(p) ; } // 如果为保存文件数据成功 if ( p->SaveData( index, data, len , desc ) ) { if( ! binsert ) _index.erase( key ) ; delete p ; return true; } OUT_INFO( NULL, 0, "scpmedia", "save data macid %s , total %d , index %d , len %d" , macid, total, index, len ) ; _queue.push( p ) ; if ( binsert ) { // 如果为多包处理 _index.insert( pair<string,CScpFile*>( key, p ) ) ; } return false ; } }
// 向MSG上传消息 void MsgClient::HandleMsgData(const char *macid, const char *data, int len) { OUT_INFO( NULL, 0, "msg", "HandleUpMsgData %s", data ); string val; if (!_session.GetSession(macid, val)) { SendOnlineData(data, len); //OUT_ERROR( NULL, 0, macid, "Get Session Failed, Data %s" , data ); return; } User user = _online_user.GetUserByUserId(val); if (user._user_id.empty() || user._fd == NULL ) { OUT_ERROR( NULL, 0, macid, "Get User empty , User id: %s, data %s" , val.c_str() , data ); return; } // 发送数据 SendData(user._fd, data, len); }
void TcpClient::on_data_arrived(socket_t *sock, const void* data, int len) { const char *ip = sock->_szIp; unsigned int port = sock->_port; OUT_HEX(ip, port, "RECV", (char* )data, len); User user = _online_user.GetUserBySocket(sock); if (user._user_id.empty() || user._ext_ptr == NULL) { return; } user._last_active_time = time(NULL); _online_user.SetUser(user._user_id, user); ITcpServer *svr = (ITcpServer*) user._ext_ptr; if (!svr->HandleData(user._user_id, data, len)) { OUT_INFO(sock->_szIp, sock->_port, "SEND", "%s, source connect invalid", user._user_id.c_str()); _online_user.DeleteUser(user._user_id); CloseSocket(sock); } }
// 向MSG上传消息 bool MsgClient::HandleUpMsgData( const char *code, const char *data, int len ) { OUT_INFO( NULL, 0, "msg", "HandleUpMsgData %s", data ) ; if ( strstr( code, "_" ) != NULL ) { string userid ; // 取得MACID对应的接入数据 if ( !_session.GetSession( code, userid , false ) ) { OUT_ERROR( NULL, 0, "Msg", "find macid %s userid failed, data: %s", code, data ) ; return false; } User user = _online_user.GetUserByUserId( userid ) ; if ( user._user_id.empty() || user._user_state != User::ON_LINE ) { OUT_ERROR( NULL, 0, userid.c_str() , "%s ,user not online, data: %s", code, data ) ; return false ; } // 发送数据 return SendData( user._fd, data, len ) ; } // 根据MSG的码进行数据路由 return SendDataToUser( code, data, len ) ; }
// 保存数据包处理 bool CScpMedia::SavePackage( int fd, const char *macid, int id, int total, int index, int type, int ftype,int event,int channel, const char * data, int len , const char *gps ) { if ( data == NULL || len == 0 ) { return false ; } MultiDesc *pdesc = new MultiDesc; // 保存SCP文件数据,如果分块文件,则直接保存在内存中处理 if ( ! _scp_manager.SaveScpFile( fd, macid, id ,total, index, type, ftype, event, channel, data, len , gps , pdesc ) ){ OUT_INFO( NULL, 0, "scpmedia" , "save macid %s , id %d , data len %d , index %d , total %d , type %d , ftype %d, event %d ,channel %d , %s:%d" , macid, id, len, index, total, type, ftype, event, channel, __FILE__, __LINE__ ) ; delete pdesc ; return false ; } // 存放数据,交以后线程上传FTP if ( ! _queuethread->Push( pdesc ) ) { delete pdesc ; return false ; } return true ; }
void PasServer::TimeWork() { OUT_INFO( NULL, 0, NULL, "void PasServer::TimeWork()"); time_t last = time(NULL); //做超时检测使用 while (1) { if (!Check()) break; time_t now = time(NULL); if (now - last > 30) { float count = 0, speed = 0; _allstat.GetFlux(count, speed); OUT_RUNNING( NULL, 0, "ONLINE", "total speed: %f, flux: %fkb, %s", count, (float)speed/(float)DF_KB, _datastat.GetFlux().c_str() ); last = now; } HandleOfflineUsers(); sleep(3); } }
void PasClient::HandleCtrlData( socket_t *sock, const char *data, int len ) { PccUser user ; if ( ! _user.GetUser( sock, user ) ) { if ( ! check_udp_fd(sock) ) { OUT_ERROR( sock->_szIp, sock->_port, "Recv", "get user failed, recv fd %d data %s", sock->_fd, (char *)data ) ; return ; } // 如果为UDP就直接收了 PccUser &tmp = _user.GetUser(false) ; user = tmp ; } _user.Update( PCC_USER_ACTVIE, user._tcp ) ; vector<string> vecline ; // 拆分数据 if ( ! splitvector( data, vecline, "\r\n", 0 ) ){ OUT_ERROR( sock->_szIp, sock->_port, "Recv", "fd %d, data error: %s", sock->_fd, data ) ; return ; } OUT_RECV( sock->_szIp, sock->_port, user._username.c_str(), "fd %d, Recv: %s", sock->_fd, data ) ; // 处理所有拆分后的数据 for ( int i = 0; i < vecline.size(); ++ i ) { string &line = vecline[i] ; if ( line.empty() ) continue ; vector<string> veck ; if ( ! splitvector( line, veck, " ", 0 ) ) continue ; if ( veck.size() < 3 ) continue ; if ( veck[0] != "SZE" || veck[2].empty() ) continue ; if ( veck[1] == "L" ) { // 控制通道连接 const char *lkey = veck[2].c_str() ; if ( strcmp( lkey, "-1") == 0 || strcmp( lkey, "-2") == 0 ) { if ( strcmp( lkey, "-1") == 0 ) { OUT_ERROR( sock->_szIp, sock->_port, user._username.c_str(), "invalid connected fd %d" , sock->_fd ) ; } else if ( strcmp( lkey, "-2") == 0 ) { OUT_ERROR( sock->_szIp, sock->_port, user._username.c_str(), "in reconnect time fd %d", sock->_fd ) ; } else { OUT_ERROR( sock->_szIp, sock->_port, user._username.c_str(), "unkown error fd %d", sock->_fd ) ; } CloseSocket( sock ) ; } else { char buf[1024] = {0}; // 连接成功需要发送用户鉴权 sprintf( buf, "SZ A %s|%s|%s\r\n", veck[2].c_str(), user._username.c_str(), user._password.c_str() ) ; SendData( sock, buf, strlen(buf) ) ; OUT_SEND( sock->_szIp, sock->_port, user._username.c_str(), "Send %s", buf ) ; } } else if ( veck[1] == "A" || veck[1] == "P" ) { // 用户鉴权, 或者数据通道注册 const char *ckey = veck[2].c_str() ; if ( strcmp( ckey, "-1") == 0 || strcmp( ckey, "-2") == 0 ) { if ( strcmp( ckey, "-1") == 0 ) { OUT_ERROR( sock->_szIp, sock->_port, user._username.c_str(), "%s fd %d failed", ( veck[1] == "A" ) ? "auth" : "register data way",sock->_fd ) ; } else if ( strcmp( ckey, "-2") == 0 ) { OUT_ERROR( sock->_szIp, sock->_port, user._username.c_str(), "lkey %s invalid fd %d", user._srv_key.c_str(), sock->_fd ) ; } else { OUT_ERROR( sock->_szIp, sock->_port, user._username.c_str(), "unkown error fd %d", sock->_fd ) ; } CloseSocket( sock ) ; continue ; } PccUser &tmp = _user.GetUser( ( veck[1] == "A" ) ) ; tmp._srv_key = veck[2] ; // 如果鉴权成功,保存鉴权码 tmp.Update( PCC_USER_ACTVIE ) ; if ( veck[1] == "A" ) { tmp.SetOnline() ; } OUT_INFO( sock->_szIp, sock->_port, tmp._username.c_str(), "Login success, fd %d, login fd %d tcp %d, srv key %s" , sock->_fd , tmp._fd ? tmp._fd->_fd : -1, tmp._tcp , veck[2].c_str() ) ; } else if ( veck[1] == "N" ) { // 控制通道握手维护 OUT_INFO( sock->_szIp, sock->_port, user._username.c_str(), "NOOP" ) ; } } }
void MsgClient::HandleSession( socket_t *sock, const char *data, int len ) { string line = data; vector<string> vec_temp ; if ( ! splitvector( line, vec_temp, " " , 1 ) ) { return ; } string head = vec_temp[0]; if (head == "LACK") { /* RESULT >=0:权限值 -1:密码错误 -2:帐号已经登录 -3:帐号已经停用 -4:帐号不存在 -5:sql查询失败 -6:未登录数据库 */ int ret = atoi( vec_temp[1].c_str() ) ; switch( ret ) { case 0: case 1: case 2: case 3: { User user = _online_user.GetUserBySocket( sock ) ; if( user._user_id.empty() ) { OUT_WARNING(sock->_szIp, sock->_port, NULL,"Can't find the syn_user"); return; } user._user_state = User::ON_LINE ; user._last_active_time = time(NULL) ; // 重新处理用户状态 _online_user.SetUser( user._user_id, user ) ; OUT_CONN( sock->_szIp, sock->_port, user._user_name.c_str(), "Login success, fd %d access code %d" , sock->_fd, user._access_code ) ; // 登陆成功,如果为数据订制连接就直接需要处理发送订阅处理 if ( user._user_type == "DMDATA" ) LoadSubscribe( user ) ; } break ; case -1: { OUT_ERROR( sock->_szIp, sock->_port, NULL , "LACK,password error!"); } break ; case -2: { OUT_ERROR( sock->_szIp, sock->_port, NULL ,"LACK,the user has already login!"); } break ; case -3: { OUT_ERROR( sock->_szIp, sock->_port, NULL, "LACK,user name is invalid!"); } break ; default: { OUT_ERROR( sock->_szIp, sock->_port, NULL, "unknow result" ) ; } break; } // 如果返回错误则直接处理 if ( ret < 0 ) { _tcp_handle.close_socket(sock); } } else if (head == "NOOP_ACK") { User user = _online_user.GetUserBySocket( sock ) ; user._last_active_time = time(NULL) ; _online_user.SetUser( user._user_id, user ) ; OUT_INFO( sock->_szIp, sock->_port, user._user_name.c_str() , "NOOP_ACK"); } else { OUT_WARNING( sock->_szIp, sock->_port, NULL, "except message:%s", (const char*)data ); } }
// 处理809协议的数据 void CPccServer::HandleOutData( socket_t *sock, const char *data, int len ) { // 处理809 if (data == NULL || len < (int)sizeof(Header)) { OUT_HEX( sock->_szIp, sock->_port, "PccServer" , (const char *)data, len ) ; return; } Header *header = (Header *) data; unsigned int access_code = ntouv32(header->access_code); string str_access_code = uitodecstr(access_code); unsigned short msg_type = ntouv16(header->msg_type); const char *ip = sock->_szIp ; unsigned int port = sock->_port ; // 处理加解密数据 EncryptData( (unsigned char*) data , len , false ) ; OUT_RECV( ip, port, str_access_code.c_str(), "%s,from pccserver", _proto_parse.Decoder(data,len).c_str() ) ; OUT_HEX( ip, port, str_access_code.c_str(), data, len ) ; if (msg_type == DOWN_CONNECT_REQ){ // 连接请求 User user = _online_user.GetUserByUserId(str_access_code); if ( user._fd != NULL && user._fd != sock ) { CloseSocket(user._fd) ; } DownConnectReq* req = (DownConnectReq*) data; user._fd = sock; user._ip = ip ; user._port = port ; user._login_time = time(0); user._msg_seq = 0; user._user_id = str_access_code ; user._access_code = access_code ; user._user_state = User::ON_LINE; //一定要设置这个,因为在下行链路还没有建立起来的时候,第一次登录的时候上的那个是不能执行的。 user._last_active_time = time(0); // 添加用户 if ( ! _online_user.AddUser( str_access_code, user ) ){ _online_user.SetUser( str_access_code, user ) ; } DownConnectRsp resp; resp.header.msg_seq = ntouv16(_proto_parse.get_next_seq()); resp.header.access_code = req->header.access_code; resp.result = 0; if ( SendCrcData( sock,(const char *)&resp,sizeof(resp) ) ) { OUT_INFO(ip,port,str_access_code.c_str(),"DOWN_CONNECT_REQ: send DOWN_CONNECT_RSP downlink is online"); } else { OUT_ERROR(ip,port,str_access_code.c_str(),"DOWN_CONNECT_REQ: send DOWN_CONNECT_RSP downlink is online failed"); } // 更新连接状态 _pEnv->GetPasClient()->UpdateSlaveConn( access_code , CONN_CONNECT ) ; return; } User user = _online_user.GetUserBySocket( sock ); if (user._user_id.empty()){ OUT_ERROR(ip,port,str_access_code.c_str(),"msg type %04x, user havn't login,close it %d", msg_type, sock->_fd ); CloseSocket( sock ); return; } // 如果为心跳 if (msg_type == DOWN_LINKTEST_REQ){ OUT_RECV(ip,port,user._user_id.c_str(),"DOWN_LINKTEST_REQ"); DownLinkTestRsp resp; resp.header.access_code = header->access_code; resp.header.msg_seq = ntouv32(_proto_parse.get_next_seq()); if ( SendCrcData( sock, (const char*) &resp, sizeof(resp) ) ) OUT_SEND(ip,port,user._user_id.c_str(),"DOWN_LINKTEST_RSP"); else OUT_ERROR(ip,port,user._user_id.c_str(),"DOWN_LINKTEST_RSP") ; } else if (msg_type == DOWN_DISCONNECT_REQ ) { // 从链路注销请求 OUT_RECV(ip,port,user._user_id.c_str(),get_type(msg_type)); DownDisconnectRsp resp ; resp.header.msg_len = ntouv32( sizeof(resp) ) ; resp.header.msg_type = ntouv16( DOWN_DISCONNECT_RSP ) ; resp.header.access_code = header->access_code ; resp.header.msg_seq = ntouv32( _proto_parse.get_next_seq() ) ; if ( SendCrcData( sock, (const char*) &resp, sizeof(resp) ) ) OUT_SEND(ip,port,user._user_id.c_str(),"DOWN_DISCONNECT_RSP"); else OUT_ERROR(ip,port,user._user_id.c_str(),"DOWN_DISCONNECT_RSP") ; // 这里由主链路来主动关闭连接,置离线状态由线程自动回收链路 // user._user_state = User::OFF_LINE ; } else if (msg_type == DOWN_DISCONNECT_INFORM){ // 主链路消息 //不管它,由定时线程来完成。 OUT_RECV(ip,port,user._user_id.c_str(),get_type(msg_type)); } else if (msg_type == DOWN_CLOSELINK_INFORM ){ // 来自主链路 } else{ // 直接到CLIENT处理 _pEnv->GetPasClient()->HandlePasDownData( access_code, data, len ) ; } user._last_active_time = time(0); _online_user.SetUser(user._user_id,user); }
// 加载MSG的用户文件 bool MsgClient::LoadMsgUser( const char *userfile ) { if ( userfile == NULL ) return false ; char buf[1024] = {0}; FILE *fp = NULL; fp = fopen( userfile, "r" ); if (fp == NULL){ OUT_ERROR( NULL, 0, NULL, "Load msg user file %s failed", userfile ) ; return false; } int count = 0 ; while (fgets(buf, sizeof(buf), fp)){ unsigned int i = 0; while (i < sizeof(buf)){ if (!isspace(buf[i])) break; i++; } if (buf[i] == '#') continue; char temp[1024] = {0}; for (int i = 0, j = 0; i < (int)strlen(buf); ++ i ){ if (buf[i] != ' ' && buf[i] != '\r' && buf[i] != '\n'){ temp[j++] = buf[i]; } } string line = temp; //1:10.1.99.115:8880:user_name:user_password:A3 vector<string> vec_line ; if ( ! splitvector( line, vec_line, ":" , 7 ) ){ continue ; } if ( vec_line[0] != MSG_USER_TAG ) { continue ; } User user ; user._user_id = vec_line[0] + vec_line[1] ; user._access_code = atoi( vec_line[1].c_str() ) ; user._ip = vec_line[2] ; user._port = atoi( vec_line[3].c_str() ) ; user._user_name = vec_line[4] ; user._user_pwd = vec_line[5] ; user._user_type = vec_line[6] ; user._user_state = User::OFF_LINE ; user._socket_type = User::TcpConnClient ; user._connect_info.keep_alive = AlwaysReConn ; user._connect_info.timeval = 30 ; // 添加到用户队列中 _online_user.AddUser( user._user_id, user ) ; ++ count ; } fclose(fp); fp = NULL; OUT_INFO( NULL, 0, NULL, "load msg user success %s, count %d" , userfile , count ) ; printf( "load msg user count %d success %s\n" , count, userfile ) ; return true ; }
// 保存文件 bool CScpMedia::CScpFile::SaveData( const int index, const char * data, int len , MultiDesc *desc ) { // 先检测数据的正确性 if ( data == NULL || len == 0 || index > _desc._total ){ OUT_ERROR( NULL, 0, "ftp" , "file index %d total %d len %d" , index, _desc._total , len ) ; return false ; } _last = time(NULL) ; // 如果只有一个数据包直接保存 if ( _desc._total == 1 ) { // 保存到本地文件目录 if ( ! AppendFile( _desc._path.c_str(), data, len ) ) { OUT_ERROR( NULL, 0, "scpmedia" , "ftp save file to path %s failed" , _desc._path.c_str() ) ; return false ; } // 拷贝返回数据 desc->Copy( _desc ) ; OUT_INFO( NULL, 0, "scpmedia" , "ftp save file path %s" , _desc._path.c_str() ) ; return true ; } // 如果索引值超过了最大包数则直接返回 if ( index > (int)_vec.size() ) { OUT_ERROR( NULL, 0, "scpmedia" , "ftp save file index %d over max total %d" , index, _vec.size() ) ; return false ; } // 取得索引值 MemFile *p = _vec[index-1] ; if ( p->_ptr == NULL ) { // 如第一上传的数据才记录上传正确的包数 ++ _cur ; // 开辟新的空间 p->_ptr = new char[len] ; } else { // 如果这一次传上数据长度要大于上一次上传长度 if ( p->_len < len ) { // 释放原来的内存 delete [] p->_ptr ; p->_ptr = new char[len] ; } } p->_len = len ; p->_index = index ; memcpy( p->_ptr, data, len ) ; if ( (int)_cur != _desc._total ) { OUT_INFO( NULL, 0, "scpmedia" , "scp save index file %d, current count %d total %d" , index, _cur, _desc._total ) ; return false ; } // 如果所有数据包都保存成功,则直接保存成文件 for ( size_t i = 0; i < _vec.size(); ++ i ) { p = _vec[i] ; if ( p->_ptr == NULL || p->_len == 0 ){ continue; } // 保存文件,处理文件各块 AppendFile( _desc._path.c_str(), p->_ptr, p->_len ) ; } // 拷贝返回数据 desc->Copy( _desc ) ; OUT_INFO( NULL, 0, "scpmedia" , "ftp save file path %s" , _desc._path.c_str() ) ; return true ; }
void PasClient::on_dis_connection( socket_t *sock ) { //专门处理底层的链路突然断开的情况,不处理超时和正常流程下的断开情况。 OUT_INFO( sock->_szIp, sock->_port, "Conn", "Recv disconnect fd %d", sock->_fd ) ; _user.DisConnect( sock ) ; }