您的位置:首页 > 移动开发 > Cocos引擎

Cocos2dX通过Java服务器向Unity传输数据二

2016-03-18 16:15 316 查看
下面介绍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, 0, false);
return true;
}

bool SocketClient::connectServer(const char* serverIP, unsigned short port)
{
if (!this->initClient())
{
return false;
}

struct sockaddr_in serverAddr;
memset(&serverAddr, 0, 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,"172.27.35.1",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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: