位置: 编程技术 - 正文

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([置顶]电影名字《收件人不详》)

  • 会计核算职能有哪些特征
  • 房产税和城镇土地使用税的区别
  • 交了进口增值税还要交增值税吗
  • 备用金为什么会变少
  • 安保公司差额征税开具发票
  • 国有独资企业交企业所得税规定
  • 进口转卖业务
  • 开办费如何做纳税调增
  • 固定资产暂估折旧能税前扣除吗
  • 计提工资和应付职工薪酬怎么不一样
  • 电子发票不小心删掉了怎么办
  • 待处理财产损益科目
  • 软件开发开增票几个点
  • 年初未交增值税借方怎么处理
  • 土地无形资产摊销年限怎么确定
  • win11不兼容
  • 主营业务收入的计算公式
  • 输入字母和数字 小学信息技术课
  • 处置固定资产增值税怎么计算
  • 月末一次加权平均和移动加权平均的区别
  • 自产应税消费品用于在建工程要交增值税吗
  • php常用的字符串函数
  • 微信小程序开发公司
  • vue中的路由守卫有哪些
  • 完美怎么用
  • php判断链表是否有环
  • 应付职工薪酬多栏式
  • 出差补贴要扣税吗
  • 对公账户名称可以是个人名字吗
  • 百度编辑器使用方法
  • mysql存储过程用什么调用
  • 发票报送日志不完整
  • 哪些企业适用于企业会计制度
  • 期权权利金的计算公式
  • 购买无形资产的入账价值包括增值税吗
  • 企业利润怎么提取出来
  • 开票明细是食品类吗
  • 库存股增加记哪一方
  • 应收账款确认无法收回的会计处理
  • 购买花卉
  • 印花税每个月都计提吗
  • 建造生产线计入什么科目
  • 税务自查补缴税款怎么办
  • 企业间贴现手续怎么办理
  • 增值税普通发票可以抵扣多少钱
  • 企业工资薪金支出怎么确认
  • 新医院会计制度什么时候实施
  • 物业管理企业应设置代管基金和代收款项账户
  • mysql exists与not exists实例详解
  • mysql5717安装及配置超详细教程
  • ubuntu 16.04.6安装教程
  • nano linux
  • ntdll.dll no matching
  • win7旗舰版系统激活密钥
  • win7旗舰系统
  • centos7 中文支持
  • ghost硬盘对拷反了
  • 关闭5gwifi
  • xp系统怎么和win7系统共享
  • ubuntu20.04换阿里源
  • xp系统修改分辨率
  • window8设置在哪里
  • linux系统基本操作命令
  • es6新增的数据结构
  • threejs加载obj模型颜色不对
  • Android GBK与UTF-8
  • 又拍云cdn配置
  • dos rd命令
  • java怎样学
  • jquery的循环
  • 关闭计算机盖的功能
  • js中overlay
  • 22号天蝎座的运势
  • jquery动态添加html代码
  • android,ios,apicloud 同时开发两个平台应用,方便简单一体化,自带svn,云编译,中文IDE
  • 税务人员廉洁自律承诺书
  • 浙江国税电子税务局
  • 沈阳税务局兑奖中心在哪
  • 海口社保一个月多少钱
  • 2018年申报时间
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设