位置: 编程技术 - 正文

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

  • 企业所得税法
  • 销项减进项余额在哪方
  • 个税换电脑了还能查到之前的申报记录吗?
  • 开票报税是什么意思
  • 超范围经营是不是就等于无证经营
  • 应付账款发生额在哪方
  • 增值税没有按时缴纳会影响开票吗
  • 在建工程全部费用化
  • 建筑企业管理部门
  • 土地使用权与房屋所有权不一致
  • 记账公司如何平衡收入成本费用?
  • 会务费税务处理
  • 金税盘增值税减免税申报明细表怎么填
  • 外籍人员工资个税
  • excel合并的单元格怎么填充序列
  • rebootandselectproperbotdevice
  • 如何解决win10系统复制文件速度
  • 成本加成法的缺点
  • 技术服务费增值税发票怎么开
  • 员工冲借款应该怎么做账
  • php基础入门教程
  • 最小全画幅的数值是多少
  • c#openxml
  • 业务招待费超出部分纳税调增分录
  • php gd库
  • 阿尔卑斯山城市
  • 清算资金往来的余额方向
  • gpts
  • vue 滚动条
  • 应收账款和其他应收款的区别
  • 补缴当年增值税税款和滞纳金如何记账
  • 二元运算例子
  • 关于眼中的世界的作文
  • 残保金季报要填上年职工人数
  • 清单发票填开注意事项
  • 单位购买防疫物资会议纪要
  • 农产品核定进项
  • 帝国cms伪静态规则
  • 经营范围没有的项目可以做吗
  • 管理费用核算的是
  • 我国的税种及税率
  • 置换房产入账价值的确定根据什么
  • 结转税金需要附件吗
  • 增资减资改变股东要交税吗
  • 日常生活中各种形式的能量的转化
  • 损益类费用科目结转本年利润是余额结转还是发生额结转
  • 加油费不征税发票怎么开
  • 金税盘技术维护费
  • 组织机构代码证和统一社会信用代码的关系
  • 建筑业营改增后,人工费不存在可抵扣
  • 食品生产企业成本怎么核算
  • 总账和明细账的保管期限
  • 视同销售的几种情况
  • 商品流通企业有哪些企业
  • win7 win8.1双系统安装教程
  • 拒绝访问.exe出错
  • centos如何禁ping
  • u极速u盘装系统
  • win7 系统设置
  • win10系统预览版
  • winxp网络设置在哪
  • win7 64位系统使用360安全浏览器在网页中播放视频出现花屏的解决方法
  • win7系统本地连接图标不见了
  • Win10系统如何打开任务管理器
  • win10图标预览
  • cocos2d教程
  • bootstrap导航都有哪些
  • java的gui框架
  • javascript教程完整版
  • Python编程给定a=1,b=4,输出a+b的值
  • python deque
  • opencv识别结果输出
  • 江西国税局电子税务局
  • 国家税务总局会议管理办法
  • 企业所得税问题的研究论文
  • 天津国税局电子税务局
  • 合规管理的基本要求
  • 珠海市高新区国土局局长
  • 重庆市大学生田径锦标赛
  • 个人所得税计算扣除五险一金吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设