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

Cocos2d-x 3.x利用Socket创建客户端和服务端,第1张

概述From:http://cn.cocos2d-x.org/tutorial/show?id=2193 Socket基类 包括Socket的初始化,主要是Windows上,在Android上就不需要了。 如果平台为Windows,则需要初始化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SocketBase::SocketBase() {      _bIni

From:http://cn.cocos2d-x.org/tutorial/show?ID=2193

Socket基类

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

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SocketBase::SocketBase() { _bInitSuccess= false ; # if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) WORD wVersionRequested; wVersionRequested=MAKEWORD(2,0); WSADATAwsaData; int nRet=WSAStartup(wVersionRequested,&wsaData); if (nRet!=0) { fprintf (stderr, "InitilizeError!\n" ); return ; } _bInitSuccess= true ; #endif }

当然析构时也要释放资源

1 2 3 4 5 6 7 8 9 SocketBase::~SocketBase() { # if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) if (_bInitSuccess) { WSACleanup(); } #endif }

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


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

1 2 3 4 5 6 7 8 voID SocketBase::closeConnect(HSocketsocket) { # if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) close(socket); #elif(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) closesocket(socket); #endif }

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

1 2 3 4 5 6 7 8 bool SocketBase::error(HSocketsocket) { # if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) return socket==SOCKET_ERROR; #elif(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) return socket<0; #endif }

SocketBase.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @H_406_502@ 32 33 34 35 36 37 38 39 40 41 42 43 #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_WIN32) #include<WinSock2.h> #pragmacomment(lib,"WS2_32.lib") #defineHSocketSOCKET //对于androID平台 #elif(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) #include<arpa/inet.h> //forinet_** #include<netdb.h> //forgethost** #include<netinet/in.h> //forsockaddr_in #include<sys/types.h> //forsocket #include<sys/socket.h> //forsocket #include<unistd.h> #include<st@R_301_6901@.h> //forprintf #include<stdlib.h> //forexit #include<string.h> //forbzero #defineHSocketint #endif class SocketBase: public Ref { public : SocketBase(); ~SocketBase(); @H_406_502@ protected : voID closeConnect(HSocketsocket); bool error(HSocketsocket); protected : std::mutex_mutex; private : bool _bInitSuccess; }; #endif


服务端

初始化服务端

向指定客户端发送消息

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

向所有客户端发送消息

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

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

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

当有新连接时的回调函数

1 std::function< voID (HSocketsocket)>onNewConnection;

当有消息时的回调函数

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

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

1 std::function< voID (HSocketsocket)>ondisconnect;

SocketServer.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @H_406_502@ 32 33 34 35 36 37 38 #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(HSocketsocket, int count); voID sendMessage( const char *data, int count); std::function< voID ( const char *ip)>onStart; std::function< voID (HSocketsocket)>onNewConnection; std::function< voID ( const char *data, int count)>onRecv; std::function< voID (HSocketsocket)>ondisconnect; private : bool initServer(); voID acceptClIEnt(); voID acceptFunc(); voID newClIEntConnected(HSocketsocket); voID recvMessage(HSocketsocket); private : HSocket_socketServer; @H_406_502@ private : std::List<HSocket>_clIEntSockets; }; #endif

SocketServer.cpp

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @H_406_502@ 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 @H_525_1404@ 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 @H_559_1502@ 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 @H_502_1582@ 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 #include"SocketServer.h" SocketServer*SocketServer::create() { autoserver= 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()) @H_406_502@ { return false ; } return true ; } bool SocketServer::initServer() { if (_socketServer!=0) { this ->closeConnect(_socketServer); } _socketServer=socket(AF_INET,SOCK_STREAM,0); if (error(_socketServer)) { log ( "socketerror!" ); _socketServer=0; return false ; } do { struct sockaddr_insockAddr; memset (&sockAddr, sizeof (sockAddr)); sockAddr.sin_family=AF_INET; sockAddr.sin_port=htons(8000); sockAddr.sin_addr.s_addr=htonl(INADDR_ANY); int ret=0; ret=bind(_socketServer,( const sockaddr*)&sockAddr, sizeof (sockAddr)); @H_525_1404@ if (ret<0) { log ( "binderror!" ); break ; } ret=Listen(_socketServer,5); if (ret<0) { log ( "Listenerror!" ); break ; } //start char hostname[256]; 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 ( "startserver!" ); 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_insockAddr; while ( true ) { HSocketclIEntSock=accept(_socketServer,(sockaddr*)&sockAddr,&len); if (error(clIEntSock)) { @H_559_1502@ log ( "accepterror!" ); break ; } this ->newClIEntConnected(clIEntSock); } } voID SocketServer::newClIEntConnected(HSocketsocket) { log ( "newconnect!" ); _clIEntSockets.push_back(socket); std:: thread th(&SocketServer::recvMessage, this ,socket); th.detach(); if (onNewConnection!=nullptr) { onNewConnection(socket); } } voID SocketServer::recvMessage(HSocketsocket) { char buff[1024]; 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); } @H_502_1582@ _mutex.unlock(); break ; } else { buff[ret]=0; log ( "recvmsg:%s" ,buff); if (ret>0&&onRecv!=nullptr) { onRecv(buff,ret); } } } } voID SocketServer::sendMessage(HSocketsocket, int count) { for (auto&sock:_clIEntSockets) { if (sock==socket) { int ret=send(socket,data,count,0); if (ret<0) { log ( "senderror!" ); } break ; } } } voID SocketServer::sendMessage( const char *data, int count) { for (auto&socket:_clIEntSockets) { int ret=send(socket,0); if (ret<0) { log ( "senderror!" ); } } }


客户端

连接服务端

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

向服务端发送消息

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

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

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

断开连接的回调函数

1 std::function< voID ()>ondisconnect;

SocketClIEnt.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @H_406_502@ 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 @H_525_1404@ 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 #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,0); if (error(_socketServer)) @H_406_502@ { log ( "initclIEnterror!" ); _socektClIEnt=0; return false ; } return true ; } bool SocketClIEnt::connectServer( const char *serverIP,unsigned short port) { if (! this ->initClIEnt()) { return false ; } struct sockaddr_inserverAddr; memset (&serverAddr, 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 ; @H_525_1404@ } 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 ( "recverror" ); 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,0); if (ret<0) { log ( "senderror!" ); } } }
总结

以上是内存溢出为你收集整理的Cocos2d-x 3.x利用Socket创建客户端和服务端全部内容,希望文章能够帮你解决Cocos2d-x 3.x利用Socket创建客户端和服务端所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1031277.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-23
下一篇2022-05-23

发表评论

登录后才能评论

评论列表(0条)