位置: 编程技术 - 正文

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

  • 企业所得税更正申报要交滞纳金吗
  • 企业增值税是什么科目
  • 增值税专用发票使用规定 最新
  • 附加税减征额怎么做分录
  • 专利在审可以入库吗
  • 商业汇票的存款期限
  • 出租不动产房屋交什么税
  • 延迟取得发票的原因
  • 行政单位预算外资金收入
  • 资本公积在现金流量表哪里体现
  • 流动比率与速动比率之差等于现金比率
  • 是否退还投标文件
  • 未结清全额是逾期吗
  • 出口不退税怎么做账
  • 发票销项负数的会计分录怎么做?
  • 进项税额转出报税填哪个表
  • 资产负债表和利润表的利润不一致
  • 总分机构账务处理
  • 开错的发票正常入账吗
  • 企业所得税递增是什么意思
  • 现金返利怎么做账
  • 预收房款不征税发票
  • 同一控制下的企业合并的会计核算方法
  • 一年期电子银行承兑汇票
  • 买东西退税退的是什么税
  • 政府减免税款如何做账
  • 所得税申报填写
  • 购买转账支票费用
  • 员工 意外保险
  • mac怎么彻底删除一个软件
  • 个体户流水过大怎么避税
  • php获取指定日期是星期几
  • 农产品进项税额转出怎么算
  • url示例
  • 提租补贴应计入什么科目
  • 爬虫10054
  • nginx ss
  • 金融商品转让业务包括
  • 公司注销未分配利润会计分录
  • php的lamp
  • 自然人税收管理系统扣缴客户端app
  • 写字楼租赁房产税
  • vue 可拖拽
  • 论文resit
  • 小程序微信认证
  • c语言中数组怎么用
  • 帝国cms8.0
  • 分公司产生的费用怎么报销
  • 一条sql更新多条记录
  • 哪些科目会影响损益
  • 发票还没认证可以报销吗
  • 减免税额月底怎么结转
  • 水利基金和印花税的计税依据一样吗
  • 暂估有几种处理方法
  • 购建固定资产属于投资活动吗
  • 计算不含税金额
  • 差旅费借记什么科目
  • 无形资产管理的特点
  • 财务费用包括哪些费用
  • 员工福利费怎么做账
  • sql server本地服务器地址如何查看
  • linux的lvm扩容
  • 安装win8.1系统步骤
  • ubuntu下安装QT教程
  • ubuntu debian
  • win7打开文件夹都是独立的窗口
  • win8.1界面如何改为win7
  • linux br0配置
  • 驱动人生公司怎么样
  • win7系统点击图标没反应
  • microsoft build
  • node 内存泄漏
  • 备份文件并上传到网盘
  • shell脚本运行linux命令
  • python django事务transaction源码分析详解
  • unity如何动态刷新滚动列表
  • nodejs开启多线程
  • 如何在android studio中导入其他包
  • Android eclipse for mac redo 快捷键
  • 浙江国税qzzn
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设