下面介绍Cocos2dX的相关代码,这里挺郁闷的。开始的TCP协议是基于Linux的,也就是说只能用Eclipse软件编辑,本身能用,但是它调试太慢了,受不了,于是找到了c++的socket,于是把两者结合一起,调试时用VS,发布时用Eclipse,这样就爽了,但还有小问题,不过目前不用解决,就是如果发布IOS,还有加代码。我查了Cocos的官方文件,他们用的是socket.IO,这个很好,但是没时间研究了,以后开发IOS时,再深入研究吧。
废话不说,代码如下:
/* * SocketBase.h * * Created on: 2016年3月8日 * Author: Administrator */ #ifndef SOCKETBASE_H_ #define SOCKETBASE_H_ #include "cocos2d.h" #include <list> #include <thread> USING_NS_CC; #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) #include <WinSock2.h> #pragma comment(lib,"WS2_32.lib") #define HSocket SOCKET #elif(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) //#include <error.h> #include <arpa/inet.h> // for inet_** #include <netdb.h> // for gethost** #include <netinet/in.h> // for sockaddr_in #include <sys/types.h> // for socket #include <sys/socket.h> // for socket #include <unistd.h> #include <stdio.h> // for printf #include <stdlib.h> // for exit #include <string.h> // for bzero #define HSocket int #endif enum MessageType { DISCONNECT,RECEIVE,NEW_CONNECTION }; class SocketMessage { private: MessageType msgType; Data* msgData; public: SocketMessage(MessageType type,unsigned char* data,int dataLen) { msgType = type; msgData = new Data(); msgData->copy(data,dataLen); } SocketMessage(MessageType type){ msgType = type; msgData = nullptr; } Data* getMsgData(){ return msgData; } MessageType getMsgType(){ return msgType; } ~SocketMessage() { if (msgData)CC_SAFE_DELETE(msgData); } }; class SocketBase:public Ref { public: SocketBase(); ~SocketBase(); bool nonBlock(HSocket socket); protected: void closeConnect(HSocket socket); bool error(HSocket socket); protected: std::mutex _mutex; private: bool _bInitSuccess; }; #endif /* SOCKETBASE_H_ */
/* * SocketBase.cpp * * Created on: 2016年3月8日 * Author: Administrator */ #include "SocketBase.h" SocketBase::SocketBase() { _bInitSuccess = false; #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) WORD wVersionRequested; wVersionRequested = MAKEWORD(2,0); WSADATA wsaData; int nRet = WSAStartup(wVersionRequested,&wsaData); if (nRet != 0) { fprintf(stderr,"Initilize Error!\n"); return; } _bInitSuccess = true; #endif } SocketBase::~SocketBase() { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) if (_bInitSuccess) { WSACleanup(); } #endif } void SocketBase::closeConnect(HSocket socket) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) close(socket); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) closesocket(socket); #endif } bool SocketBase::error(HSocket socket) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) return socket == SOCKET_ERROR; #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) return socket < 0; #endif } bool SocketBase::nonBlock(HSocket socket) { //#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) // // int flags; // flags = fcntl(socket,F_GETFL,0); // flags != O_NONBLOCK; // if (fcntl(socket,F_SETFL,flags) < 0) // { // return false; // } //#else // u_long ulOn; // ulOn = 1; // if (ioctlsocket(socket,FIONBIO,&ulOn) == SOCKET_ERROR) // { // return false; // } //#endif return true; }
/* * SocketClient.h * * Created on: 2016年3月8日 * Author: Administrator */ #ifndef SOCKETCLIENT_H_ #define SOCKETCLIENT_H_ #include "SocketBase.h" class SocketClient :public SocketBase { public: static SocketClient* construct(); void destroy(); bool connectServer(const char* serverIP,unsigned short port); void sendMessage(const char* data,int count); void sendInt(int num); std::function<void(const char* data,int count)> onRecv; std::function<void()> onDisconnect; void update(float dt); CC_CONSTRUCTOR_ACCESS: SocketClient(void); ~SocketClient(void); private: bool initClient(); void recvMessage(); void clear(); private: HSocket _socketServer; HSocket _socektClient; std::list<SocketMessage*> _UIMessageQueue; std::mutex _UIMessageQueueMutex; }; #endif /* SOCKETCLIENT_H_ */
/* * SocketClient.cpp * * Created on: 2016年3月8日 * Author: Administrator */ #include "SocketClient.h" SocketClient* SocketClient::construct() { SocketClient* client = new SocketClient; return client; } void SocketClient::destroy() { delete this; } SocketClient::SocketClient(void) : onRecv(nullptr),_socektClient(0) { } SocketClient::~SocketClient(void) { this->clear(); } void SocketClient::clear() { if (_socektClient != 0) { _mutex.lock(); this->closeConnect(_socektClient); _mutex.unlock(); } for (auto msg : _UIMessageQueue) { CC_SAFE_DELETE(msg); } _UIMessageQueue.clear(); Director::getInstance()->getScheduler()->unscheduleAllForTarget(this); } bool SocketClient::initClient() { this->clear(); _socektClient = socket(AF_INET,SOCK_STREAM,0); if (error(_socketServer)) { log("init client error!"); _socektClient = 0; return false; } Director::getInstance()->getScheduler()->scheduleUpdate(this,false); return true; } bool SocketClient::connectServer(const char* serverIP,unsigned short port) { if (!this->initClient()) { return false; } struct sockaddr_in serverAddr; memset(&serverAddr,sizeof(struct sockaddr_in)); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); serverAddr.sin_addr.s_addr = inet_addr(serverIP); int ret = 0; ret = connect(_socektClient,(struct sockaddr*)&serverAddr,sizeof(struct sockaddr)); if (ret < 0) { _socektClient = 0; return false; } std::thread recvThread(&SocketClient::recvMessage,this); recvThread.detach(); return true; } void SocketClient::recvMessage() { char recvBuf[1024]; int ret = 0; while (true) { ret = recv(_socektClient,recvBuf,sizeof(recvBuf),0); if (ret < 0) { log("recv error!"); break; } if (ret > 0 && onRecv != nullptr) { std::lock_guard<std::mutex> lk(_UIMessageQueueMutex); SocketMessage * msg = new SocketMessage(RECEIVE,(unsigned char*)recvBuf,ret); _UIMessageQueue.push_back(msg); } } _mutex.lock(); this->closeConnect(_socektClient); if (onDisconnect != nullptr) { std::lock_guard<std::mutex> lk(_UIMessageQueueMutex); SocketMessage * msg = new SocketMessage(DISCONNECT); _UIMessageQueue.push_back(msg); } _socektClient = 0; _mutex.unlock(); } void SocketClient::sendMessage(const char* data,int count) { sendInt(count); if (_socektClient != 0) { int ret = send(_socektClient,data,count,0); if (ret < 0) { log("send error!"); } } } void SocketClient::sendInt(int num){ if (_socektClient != 0){ char ch[4]; memcpy(ch,&num,4); int ret = send(_socektClient,ch,4,0); if (ret < 0){ log("send error!"); } } } void SocketClient::update(float dt) { if (_UIMessageQueue.size() == 0) { return; } _UIMessageQueueMutex.lock(); if (_UIMessageQueue.size() == 0) { _UIMessageQueueMutex.unlock(); return; } SocketMessage *msg = *(_UIMessageQueue.begin()); _UIMessageQueue.pop_front(); switch (msg->getMsgType()) { case DISCONNECT: if (onDisconnect) { this->onDisconnect(); } break; case RECEIVE: if (onRecv) { this->onRecv((const char*)msg->getMsgData()->getBytes(),msg->getMsgData()->getSize()); } break; default: break; } CC_SAFE_DELETE(msg); _UIMessageQueueMutex.unlock(); }
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" using namespace cocos2d::ui; #include "cocostudio/CocoStudio.h" #include "ui/CocosGUI.h" class HelloWorld : public cocos2d::Layer { public: Text* text; Slider* slider; CREATE_FUNC(HelloWorld); static cocos2d::Scene* createScene(); virtual bool init(); void touchEvent(cocos2d::Ref *pSender,Widget::TouchEventType type); void sliderEvent(cocos2d::Ref* sender,Slider::EventType type); }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" #include "Network/UtilTcp.h" #include "Network\SocketClient.h" //#include "Network/UtilTcp1.h" USING_NS_CC; using namespace ui; using namespace cocostudio; using namespace cocostudio::timeline; SocketClient* client; Scene* HelloWorld::createScene() { auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { if (!Layer::init()) { return false; } auto rootNode = CSLoader::createNode("MainScene.csb"); Button* closeBt = static_cast<Button*>(rootNode->getChildByTag(304)); closeBt->addTouchEventListener(CC_CALLBACK_2(HelloWorld::touchEvent,this)); slider = static_cast<Slider*>(rootNode->getChildByTag(301)); slider->setMaxPercent(100); slider->addEventListener(CC_CALLBACK_2(HelloWorld::sliderEvent,this)); text = static_cast<Text*>(rootNode->getChildByTag(302)); addChild(rootNode); //new std::thread(&UtilTcp::threadConnectServer,"172.27.35.1",59422); //new std::thread(&UtilTcp1::threadConnectTask,59422); client = SocketClient().construct(); client->connectServer("172.27.35.1",59422); return true; } void HelloWorld::sliderEvent(Ref *pSender,Slider::EventType type) { if (type == Slider::EventType::ON_PERCENTAGE_CHANGED) { text->setText(StringUtils::format("%d",slider->getPercent())); client->sendMessage("COCOS",5); client->sendInt(slider->getPercent()); // if (slider->getPercent() <= 9) { // UtilTcp::sendMessage(std::string(text->getString()).c_str(),1); // UtilTcp::sendInt(slider->getPercent()); //// client->sendMessage(std::string(text->getString()).c_str(),1); // // UtilTcp1::sendStr("COCOS",5); // UtilTcp1::sendInt(slider->getPercent()); // } // if (slider->getPercent() > 10 && slider->getPercent() < 100) { // //UtilTcp::sendInt(2); // //UtilTcp::sendMessage(std::string(text->getString()).c_str(),2); // //client->sendInt(2); //// client->sendMessage(std::string(text->getString()).c_str(),2); // UtilTcp1::sendStr("COCOS",5); // UtilTcp1::sendInt(slider->getPercent()); // } // if (slider->getPercent() == 100) { // /*UtilTcp::sendInt(3); // UtilTcp::sendMessage(std::string(text->getString()).c_str(),3);*/ //// client->sendMessage(std::string(text->getString()).c_str(),3); // UtilTcp1::sendStr("COCOS",5); // UtilTcp1::sendInt(slider->getPercent()); // } } } void HelloWorld::touchEvent(Ref *pSender,Widget::TouchEventType type) { switch (type) { case Widget::TouchEventType::BEGAN: { Director::getInstance()->end(); #if (CC_TARGET_PLATFORM==CC_PLATFORM_IOS) exit(0); #endif } break; default: break; } }