cocos2dx3.x利用sokcet建立客戶端和服務端 (二)
阿新 • • 發佈:2019-02-12
服務端:
初始化服務端
向指定客戶端傳送訊息
void sendMessage(HSocket socket, constchar* 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
當有客戶端斷開連線時的回撥函式
std::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(8000); 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[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("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[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); } _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!"); } } }