位置: 编程技术 - 正文

Cocos2d-x 3.x利用Socket创建客户端和服务端(cocos2dx schedule)

编辑:rootadmin

推荐整理分享Cocos2d-x 3.x利用Socket创建客户端和服务端(cocos2dx schedule),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:cocos怎么用,cocos 2d x,cocos2dx schedule,cocos2d schedule,cocos怎么用,cocos2d schedule,cocos2d怎么用,cocos2d怎么用,内容如对您有帮助,希望把文章链接给更多的朋友!

Socket基类

包括Socket的初始化,主要是Windows上,在Android上就不需要了。

如果平台为Windows,则需要初始化

SocketBase::SocketBase(){ _bInitSuccess = false; #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN) 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_WIN) if (_bInitSuccess) { WSACleanup(); } #endif }

因为Windows的socket()返回的socket句柄为SOCKET(UINT_PTR)与Android的socket()返回的socket句柄int, 类型不一样,所以都定义为HSocket。

对于服务端和客户端都有关闭连接,所以基类就实现共同的。

void SocketBase::closeConnect(HSocket socket) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) close(socket); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN) closesocket(socket); #endif }

当执行socket()出错时,Windows返回SOCKET_ERROR, Android返回<0,所以实现error()

bool SocketBase::error(HSocket socket) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN) return socket == SOCKET_ERROR; #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) return socket < 0; #endif }

SocketBase.h

#ifndef __SOCKET_BASE_H__#define __SOCKET_BASE_H__#include "cocos2d.h"#include <list>#include <thread>USING_NS_CC;// 对于windows平台#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN)#include <WinSock2.h>#pragma comment(lib, "WS2_.lib")#define HSocket SOCKET// 对于android平台#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)#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 class SocketBase : public Ref{ public: SocketBase(); ~SocketBase(); protected: void closeConnect(HSocket socket); bool error(HSocket socket); protected: std::mutex _mutex; private: bool _bInitSuccess;}; #endif

服务端

初始化服务端

向指定客户端发送消息

1void sendMessage(HSocket socket, const char* data, int count);Cocos2d-x 3.x利用Socket创建客户端和服务端(cocos2dx schedule)

向所有客户端发送消息

1void sendMessage(const char* data, int count);

当服务端开启后的回调函数

1std::function<void(const char* ip)> onStart;

当有新连接时的回调函数

1std::function<void(HSocket socket)> onNewConnection;

当有消息时的回调函数

1std::function<void(const char* data, int count)> onRecv;

当有客户端断开连接时的回调函数

1std::function<void(HSocket socket)> onDisconnect;

SocketServer.h

#ifndef __SOCKET_SERVER_H__#define __SOCKET_SERVER_H__ #include "SocketBase.h" class SocketServer : public SocketBase{ public: static SocketServer* create(); SocketServer(); ~SocketServer(); bool startServer(); void sendMessage(HSocket socket, const char* data, int count); void sendMessage(const char* data, int count); std::function<void(const char* ip)> onStart; std::function<void(HSocket socket)> onNewConnection; std::function<void(const char* data, int count)> onRecv; std::function<void(HSocket socket)> onDisconnect; private: bool initServer(); void acceptClient(); void acceptFunc(); void newClientConnected(HSocket socket); void recvMessage(HSocket socket); private: HSocket _socketServer; private: std::list<HSocket> _clientSockets; }; #endif

SocketServer.cpp

#include "SocketServer.h" SocketServer* SocketServer::create(){ auto server = new SocketServer; return server;} SocketServer::SocketServer() : _socketServer(0), onRecv(nullptr), onStart(nullptr), onNewConnection(nullptr){ } SocketServer::~SocketServer(){ _clientSockets.clear(); if (_socketServer) { this->closeConnect(_socketServer); }}; bool SocketServer::startServer(){ if (!initServer()) { return false; } return true;} bool SocketServer::initServer(){ if (_socketServer != 0) { this->closeConnect(_socketServer); } _socketServer = socket(AF_INET, SOCK_STREAM, 0); if (error(_socketServer)) { log("socket error!"); _socketServer = 0; return false; } do { struct sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(); sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); int ret = 0; ret = bind(_socketServer, (const sockaddr*)&sockAddr, sizeof(sockAddr)); if (ret < 0) { log("bind error!"); break; } ret = listen(_socketServer, 5); if (ret < 0) { log("listen error!"); break; } // start char hostName[]; gethostname(hostName, sizeof(hostName)); struct hostent* hostInfo = gethostbyname(hostName); char* ip = inet_ntoa(*(struct in_addr *)*hostInfo->h_addr_list); this->acceptClient(); if (onStart != nullptr) { log("start server!"); onStart(ip); } return true; } while (false); this->closeConnect(_socketServer); _socketServer = 0; return false;} void SocketServer::acceptClient(){ std::thread th(&SocketServer::acceptFunc, this); th.detach();} void SocketServer::acceptFunc(){ int len = sizeof(sockaddr); struct sockaddr_in sockAddr; while (true) { HSocket clientSock = accept(_socketServer, (sockaddr*)&sockAddr, &len); if (error(clientSock)) { log("accept error!"); break; } this->newClientConnected(clientSock); }} void SocketServer::newClientConnected(HSocket socket){ log("new connect!"); _clientSockets.push_back(socket); std::thread th(&SocketServer::recvMessage, this, socket); th.detach(); if (onNewConnection != nullptr) { onNewConnection(socket); }} void SocketServer::recvMessage(HSocket socket){ char buff[]; int ret = 0; while (true) { ret = recv(socket, buff, sizeof(buff), 0); if (ret < 0) { log("recv(%d) error!", socket); _mutex.lock(); this->closeConnect(socket); _clientSockets.remove(socket); if (onDisconnect != nullptr) { onDisconnect(socket); } _mutex.unlock(); break; } else { buff[ret] = 0; log("recv msg : %s", buff); if (ret > 0 && onRecv != nullptr) { onRecv(buff, ret); } } }} void SocketServer::sendMessage(HSocket socket, const char* data, int count){ for (auto& sock : _clientSockets) { if (sock == socket) { int ret = send(socket, data, count, 0); if (ret < 0) { log("send error!"); } break; } } } void SocketServer::sendMessage(const char* data, int count){ for (auto& socket : _clientSockets) { int ret = send(socket, data, count, 0); if (ret < 0) { log("send error!"); } } }

客户端

连接服务端

1bool connectServer(const char* serverIP, unsigned short port);

向服务端发送消息

1void sendMessage(const char* data, int count);

接受服务端数据的回调函数

1std::function<void(const char* data, int count)> onRecv;

断开连接的回调函数

1std::function<void()> onDisconnect;

SocketClient.h

#ifndef __SOCKET_CLIENT_H__#define __SOCKET_CLIENT_H__#include "SocketBase.h" class SocketClient : public SocketBase{ public: SocketClient(void); ~SocketClient(void); bool connectServer(const char* serverIP, unsigned short port); void sendMessage(const char* data, int count); std::function<void(const char* data, int count)> onRecv; std::function<void()> onDisconnect; private: bool initClient(); void recvMessage(); private: HSocket _socketServer; HSocket _socektClient;}; #endif

SocketClient.cpp

#include "SocketClient.h" SocketClient::SocketClient(void) : onRecv(nullptr), _socektClient(0){} SocketClient::~SocketClient(void){ if (_socektClient != 0) { _mutex.lock(); this->closeConnect(_socektClient); _mutex.unlock(); }} bool SocketClient::initClient(){ if (_socektClient != 0) { _mutex.lock(); this->closeConnect(_socektClient); _mutex.unlock(); } _socektClient = socket(AF_INET, SOCK_STREAM, 0); if (error(_socketServer)) { log("init client error!"); _socektClient = 0; return 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) { this->closeConnect(_socektClient); _socektClient = 0; return false; } std::thread recvThread(&SocketClient::recvMessage, this); recvThread.detach(); return true;} void SocketClient::recvMessage(){ char recvBuf[]; int ret = 0; while (true) { ret = recv(_socektClient, recvBuf, sizeof(recvBuf), 0); if (ret < 0) { log("recv error"); break; } if (ret > 0 && onRecv != nullptr) { onRecv(recvBuf, ret); } } _mutex.lock(); this->closeConnect(_socektClient); if (onDisconnect != nullptr) { onDisconnect(); } _socektClient = 0; _mutex.unlock();} void SocketClient::sendMessage(const char* data, int count){ if (_socektClient != 0) { int ret = send(_socektClient, data, count, 0); if (ret < 0) { log("send error!"); } }}

[置顶] Cocos2d-JS中使用CocosStudio资源——ListView和ScrollView 在本篇博客中,我们将简要分析一下ListView和ScrollView之间的关系,如何正确使用两个控件进行设计,目前CocosStudio对两个控件的支持状况等。一、ListView

[置顶] Cocos2d-JS中使用CocosStudio资源——帧动画(1) 在本篇博客中,我们将通过一个在Cocos2d-JS中使用从CocosStudio导出的帧动画资源的例子,来简要介绍以下内容:利用ActionTimeLine进行动画切割,如何使用导

[置顶] Cocos2d-JS中使用CocosStudio资源——帧动画(2) 在本篇博客中,我们将通过一个在Cocos2d-JS中使用从CocosStudio导出的帧动画资源的例子,来简要介绍以下内容:利用ActionTimeLine进行动画切割,如何使用导

标签: cocos2dx schedule

本文链接地址:https://www.jiuchutong.com/biancheng/368394.html 转载请保留说明!

上一篇:Unable to execute dex: Multiple dex files define Lorg/cocos2dx/lib/Cocos2dxAccelerometer

下一篇:[置顶] Cocos2d-JS中使用CocosStudio资源——ListView和ScrollView([置顶]电影名字《收件人不详》)

  • 保本理财增值税可以开票吗怎么开
  • 减免增值税如何结转
  • 发票上的金额是什么字体
  • 发票超额如何收税
  • 小规模企业所得税多少
  • 没有合同可以收违约金
  • 无形资产报废的例题
  • 软件公司购进软件会计科目
  • 互联网企业招商方案
  • 单位购置汽车如何入账
  • 员工领取产假工资怎么算
  • 确认投资收益是按照出资比例还是股权比例
  • 预收物业费是否必须开具发票
  • 购买户外用品的app
  • 委外技术服务费应归集哪个研发项目
  • 租金小规模开票税率
  • 上个月开的发票退回怎么处理?
  • 小型微利企业的条件
  • 固定资产清理账户结构
  • 私营独资企业是小微企业吗
  • 做买卖交税
  • 小企业销售费用包括
  • xp系统怎么删除打印机驱动程序
  • 资产处置收益的项目有哪些
  • php函数返回值类型
  • win10待机界面进不去系统怎么办
  • 不属于工资薪金所得的是
  • tensorflow安装教程pycharm
  • thinkphp分表
  • 应交增值税转入营业外收入摘要怎么写
  • 企业研发费用加计扣除是什么意思
  • 地税没申报罚款多少
  • vue2-elm
  • 零申报企业所得税怎么申报
  • 通用定额发票能当餐饮发票报销吗
  • phpcms默认密码
  • jquery vue.js
  • python中myqr的用法
  • 质量扣款应收账款怎么算
  • 企业所得税太高怎么合理规避
  • 进项税额有留底税额吗
  • 税务查账后如何结转
  • 固定资产投资额在财务报表中怎么体现
  • 安装sql server 2008提示重新启动计算机
  • 资产减值损失科目
  • 收到商业汇票怎么入账
  • 实物投资需要缴纳增值税吗
  • 防伪税控开票系统SOAP服务端
  • 工程主营业务收入会计分录
  • 暂估成本以后也没有票回来了
  • 公司帮别人代缴社保要交税吗
  • mysql查询id最大的记录
  • sqlserver存储过程怎么查看
  • mac安装mysql
  • Win10笔记本如何重装系统
  • 电脑ios怎么安装
  • dsapi.exe是什么
  • gacrunner.exe是什么
  • win7系统鼠标指针异常
  • linux指令系统
  • Win7如何开启蓝牙
  • cocos预加载
  • 深入理解bootstrap
  • windows升级node版本
  • javascript获取css
  • shell脚本的fi
  • android保存网络图片
  • js鼠标框选
  • js水平垂直居中怎么设置
  • 漂亮的相片超好看的
  • python 查找中文
  • 地税编码哪里查
  • 如何查看自己公司的税种
  • 国家税务总局使用
  • 浙江纳税百强2020
  • 长沙市社保中心主任
  • 福建 退休
  • 南通开发区地图高清版
  • 税费算在房价里
  • 点击正式申报前怎么操作
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设