下載地址:http://files.cnblogs.com/elephant-x/TCPSocketLibs_V1.0.rarnode
這是本身封裝的一個TCPSOCKET包,是獨立於cocos2d-x的,使用的時候,請把該項目加入到cocos2d-x裏面去,再在項目裏面包含libSocket項目和libSocket.liblinux
一、獨立線程接收,異步鏈接服務端,防止界面卡的狀況。c++
二、支持WIN32和LINUX。web
三、編譯linux時,在項目的Android.mk文件裏必須添加下面兩行:服務器
LOCAL_WHOLE_STATIC_LIBRARIES += socket_staticiphone
$(call import-module,../CustomLibs/libSocket)異步
如圖:socket
四、在Application.mk裏面加入-std=c++11,由於源代碼裏面用到了c++11(VS2012)纔有的std::bind和std::function,不支持c++11如下的編譯器函數
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 -std=c++11測試
若是是c++11如下的編譯器,能夠參考:
「function對於回調函數、將操做做爲參數傳遞等十分有用。它能夠看作是C++98標準庫中函數對象mem_fun_t, pointer_to_unary_function等的替代品。一樣的,bind()也能夠被看作是bind1st()和bind2nd()的替代品,固然比他們更強大更靈活。」
自行改寫。。
使用例子代碼,能夠拷貝到HelloCpp項目裏去測試。
.h
1 #ifndef __HELLOWORLD_SCENE_H__ 2 #define __HELLOWORLD_SCENE_H__ 3 4 #include "cocos2d.h" 5 #include "TCPSocket.h" 6 7 class GameScene : public cocos2d::CCLayer 8 { 9 public: 10 // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone 11 virtual bool init(); 12 13 // there's no 'id' in cpp, so we recommend returning the class instance pointer 14 static cocos2d::CCScene* scene(); 15 16 // a selector callback 17 void menuCloseCallback(CCObject* pSender); 18 // 註冊單個協議回調函數(樣例),參數:SOCKET_ID標識,數據包 19 void process_login(int _tag, WorldPacket & packet); 20 // 物品更新 21 void process_openbackpack(int _tag, WorldPacket & packet); 22 // 註冊單個協議回調函數(樣例),參數:SOCKET_ID標識,協議頭,數據包 23 bool process_all(int _tag, int _cmd, WorldPacket & packet); 24 // 鏈接事件 25 void OnConnect(int _tag, bool isConnect); 26 // 斷線事件 27 void onDisconnect(int _tag); 28 // implement the "static node()" method manually 29 CREATE_FUNC(GameScene); 30 }; 31 32 #endif // __HELLOWORLD_SCENE_H__
.cpp
1 #include "GameScene.h" 2 #include "AppDelegate.h" 3 #include "AppMacros.h" 4 USING_NS_CC; 5 6 CCScene* GameScene::scene() 7 { 8 // 'scene' is an autorelease object 9 CCScene *scene = CCScene::create(); 10 11 // 'layer' is an autorelease object 12 GameScene *layer = GameScene::create(); 13 14 // add layer as a child to scene 15 scene->addChild(layer); 16 17 // return the scene 18 return scene; 19 } 20 void GameScene::process_login(int _tag, WorldPacket & packet) 21 { 22 CCLOG("process_login len:%u", packet.size()); 23 // 定義協議包 24 WorldPacket newP; 25 newP.clear(); 26 newP.SetOpcode(0x00B6);// 設置協議頭 27 newP << uint16(0x00B6) 28 << uint16(0);// 協議長度 29 newP.SetLength(newP.size());// 設置協議長度 30 sSocketMgr.SendPacket(1, &newP);// 發送數據 31 } 32 33 void GameScene::process_openbackpack(int _tag, WorldPacket & packet) 34 { 35 CCLOG("process_openbackpack len:%u", packet.size()); 36 } 37 38 bool GameScene::process_all(int _tag, int _cmd, WorldPacket & packet) 39 { 40 CCLOG("process_all _tag:%u, _cmd:%u, len:%u", _tag, _cmd, packet.size()); 41 return false; 42 } 43 44 void GameScene::OnConnect(int _tag, bool isConnect) 45 { 46 // 定義協議包 47 WorldPacket packet; 48 packet.clear(); 49 packet.SetOpcode(0x0010);// 設置協議頭 50 packet << uint16(0x0010) 51 << uint16(0)// 協議長度 52 << uint8(1) 53 << uint8(0); 54 // 加入字符串數據(uint8表示字符串長度所佔字節,此處爲1字節) 55 packet.AppendPacketString<uint8>(std::string("aaa:88889083:d5956683c17d7e284d33ee295b277b52")); 56 packet.SetLength(packet.size());// 設置協議長度 57 sSocketMgr.SendPacket(1, &packet);// 發送數據 58 CCLOG("OnConnect:%u, isConnect[%u]", _tag, isConnect); 59 } 60 61 void GameScene::onDisconnect(int _tag) 62 { 63 CCLOG("desconnect:%u", _tag); 64 } 65 66 // on "init" you need to initialize your instance 67 bool GameScene::init() 68 { 69 ////////////////////////////// 70 // 1. super init first 71 if ( !CCLayer::init() ) 72 { 73 return false; 74 } 75 76 CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); 77 CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); 78 79 ///////////////////////////// 80 // 2. add a menu item with "X" image, which is clicked to quit the program 81 // you may modify it. 82 83 // add a "close" icon to exit the progress. it's an autorelease object 84 CCMenuItemImage *pCloseItem = CCMenuItemImage::create( 85 "CloseNormal.png", 86 "CloseSelected.png", 87 this, 88 menu_selector(GameScene::menuCloseCallback)); 89 90 pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 , 91 origin.y + pCloseItem->getContentSize().height/2)); 92 93 // create menu, it's an autorelease object 94 CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); 95 pMenu->setPosition(CCPointZero); 96 this->addChild(pMenu, 1); 97 98 ///////////////////////////// 99 // 3. add your codes below... 100 101 // add a label shows "Hello World" 102 // create and initialize a label 103 104 CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE); 105 106 // position the label on the center of the screen 107 pLabel->setPosition(ccp(origin.x + visibleSize.width/2, 108 origin.y + visibleSize.height - pLabel->getContentSize().height)); 109 110 // add the label as a child to this layer 111 this->addChild(pLabel, 1); 112 113 // add "HelloWorld" splash screen" 114 CCSprite* pSprite = CCSprite::create("HelloWorld.png"); 115 116 // position the sprite on the center of the screen 117 pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); 118 119 // add the sprite as a child to this layer 120 this->addChild(pSprite, 0); 121 /////////////////////////////////////////////// 122 // 建立SOCKET管理器 123 CREATE_TCPSOCKETMGR(); 124 uint64 t_begin = GetCurrentTime(); 125 // 建立並添加SOCKET,參數:服務器IP,端口,自定義的SOCKET_ID標識 126 sSocketMgr.createSocket("192.168.0.183", 7502, 1); 127 uint64 t_end = GetCurrentTime(); 128 // 註冊協議,參數:包頭,回調函數 129 sSocketMgr.register_process(0x10, SCT_CALLBACK_2(GameScene::process_login, this)); 130 sSocketMgr.register_process(0x2d, SCT_CALLBACK_2(GameScene::process_openbackpack, this)); 131 // 註冊消息截獲事件,註冊此事件後能夠截獲收到的全部消息,若回調函數返回true則本次事件會繼續分發註冊過的協議,返回false則不分發 132 sSocketMgr.register_connect(SCT_CALLBACK_2(GameScene::OnConnect, this)); 133 sSocketMgr.register_disconnect(SCT_CALLBACK_3(GameScene::onDisconnect, this)); 134 135 136 CCLOG("GameScene::init end! [%u]", t_end - t_begin); 137 /////////////////////////////////////////////// 138 return true; 139 } 140 141 void GameScene::menuCloseCallback(CCObject* pSender) 142 { 143 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) 144 CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); 145 #else 146 CCDirector::sharedDirector()->end(); 147 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 148 exit(0); 149 #endif 150 #endif 151 }