Cocos2dx中使用socket、json和pthread

来源:互联网 发布:双肩包推荐 知乎 编辑:程序博客网 时间:2024/05/17 07:51

1、首先是一个跨平台的socket类,实现如下:

ODSocket.h

/* * define file about portable socket class.  * description:this sock is suit both windows and linux * design:odison * e-mail:odison@126.com> *  */#ifndef _ODSOCKET_H_#define _ODSOCKET_H_#ifdef WIN32#include <winsock.h>typedef intsocklen_t;#else#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <arpa/inet.h>typedef intSOCKET;//#pragma region define win32 const variable in linux#define INVALID_SOCKET-1#define SOCKET_ERROR-1//#pragma endregion#endifclass ODSocket {public:ODSocket(SOCKET sock = INVALID_SOCKET);~ODSocket();// Create socket object for snd/recv databool Create(int af, int type, int protocol = 0);// Connect socketbool Connect(const char* ip, unsigned short port);//#region server// Bind socketbool Bind(unsigned short port);// Listen socketbool Listen(int backlog = 5); // Accept socketbool Accept(ODSocket& s, char* fromip = NULL);//#endregion// Send socketint Send(const char* buf, int len, int flags = 0);// Recv socketint Recv(char* buf, int len, int flags = 0);// Close socketint Close();// Get errnoint GetError();//#pragma region just for win32// Init winsock DLL static int Init();// Clean winsock DLLstatic int Clean();//#pragma endregion// Domain parsestatic bool DnsParse(const char* domain, char* ip);ODSocket& operator = (SOCKET s);operator SOCKET ();protected:SOCKET m_sock;};#endif

ODSocket.cpp

//#include "StdAfx.h"#include <stdio.h>#include "ODSocket.h"#ifdef WIN32#pragma comment(lib, "wsock32")#endifODSocket::ODSocket(SOCKET sock){m_sock = sock;}ODSocket::~ODSocket(){}int ODSocket::Init(){#ifdef WIN32/*http://msdn.microsoft.com/zh-cn/vstudio/ms741563(en-us,VS.85).aspxtypedef struct WSAData { WORD wVersion;//winsock versionWORD wHighVersion;//The highest version of the Windows Sockets specification that the Ws2_32.dll can supportchar szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYSSTATUS_LEN+1]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo; }WSADATA, *LPWSADATA; */WSADATA wsaData;//#define MAKEWORD(a,b) ((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8)) WORD version = MAKEWORD(2, 0);int ret = WSAStartup(version, &wsaData);//win sock start upif ( ret ) {//cerr << "Initilize winsock error !" << endl;return -1;}#endifreturn 0;}//this is just for windowsint ODSocket::Clean(){#ifdef WIN32return (WSACleanup());#endifreturn 0;}ODSocket& ODSocket::operator = (SOCKET s){m_sock = s;return (*this);}ODSocket::operator SOCKET (){return m_sock;}//create a socket object win/lin is the same// af:bool ODSocket::Create(int af, int type, int protocol){m_sock = socket(af, type, protocol);if ( m_sock == INVALID_SOCKET ) {return false;}return true;}bool ODSocket::Connect(const char* ip, unsigned short port){struct sockaddr_in svraddr;svraddr.sin_family = AF_INET;svraddr.sin_addr.s_addr = inet_addr(ip);svraddr.sin_port = htons(port);int ret = connect(m_sock, (struct sockaddr*)&svraddr, sizeof(svraddr));if ( ret == SOCKET_ERROR ) {return false;}return true;}bool ODSocket::Bind(unsigned short port){struct sockaddr_in svraddr;svraddr.sin_family = AF_INET;svraddr.sin_addr.s_addr = INADDR_ANY;svraddr.sin_port = htons(port);int opt =  1;if ( setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0 ) return false;int ret = bind(m_sock, (struct sockaddr*)&svraddr, sizeof(svraddr));if ( ret == SOCKET_ERROR ) {return false;}return true;}//for serverbool ODSocket::Listen(int backlog){int ret = listen(m_sock, backlog);if ( ret == SOCKET_ERROR ) {return false;}return true;}bool ODSocket::Accept(ODSocket& s, char* fromip){struct sockaddr_in cliaddr;socklen_t addrlen = sizeof(cliaddr);SOCKET sock = accept(m_sock, (struct sockaddr*)&cliaddr, &addrlen);if ( sock == SOCKET_ERROR ) {return false;}s = sock;if ( fromip != NULL )sprintf(fromip, "%s", inet_ntoa(cliaddr.sin_addr));return true;}int ODSocket::Send(const char* buf, int len, int flags){int bytes;int count = 0;while ( count < len ) {bytes = send(m_sock, buf + count, len - count, flags);if ( bytes == -1 || bytes == 0 )return -1;count += bytes;} return count;}int ODSocket::Recv(char* buf, int len, int flags){return (recv(m_sock, buf, len, flags));}int ODSocket::Close(){#ifdef WIN32return (closesocket(m_sock));#elsereturn (close(m_sock));#endif}int ODSocket::GetError(){#ifdef WIN32return (WSAGetLastError());#elsereturn (errno);#endif}bool ODSocket::DnsParse(const char* domain, char* ip){struct hostent* p;if ( (p = gethostbyname(domain)) == NULL )return false;sprintf(ip, "%u.%u.%u.%u",(unsigned char)p->h_addr_list[0][0], (unsigned char)p->h_addr_list[0][1], (unsigned char)p->h_addr_list[0][2], (unsigned char)p->h_addr_list[0][3]);return true;}


2、pthread的头文件:

#ifdef WIN32#include "../../cocos2dx/platform/third_party/win32/pthread/pthread.h"#else#include "pthread.h"#endif // WIN32

库文件:xxx\cocos2d-x-2.2.1\Debug.win32\pthreadVCE2.lib


3、关于json,发一个源工程,编译一下,就能得到库文件:http://download.csdn.net/detail/wwkaven/7923863


4、传一张配置库文件的截图:



5、一段测试代码:

#include "HelloWorldScene.h"#include "ODSocket.h"// 线程函数头文件#ifdef WIN32#include "../../cocos2dx/platform/third_party/win32/pthread/pthread.h"#else#include "pthread.h"#endif // WIN32// json#include "../../cocos2dx/platform/third_party/win32/_json/json/json.h"// string#include <string>using namespace std;USING_NS_CC;CCScene* HelloWorld::scene(){    // 'scene' is an autorelease object    CCScene *scene = CCScene::create();        // 'layer' is an autorelease object    HelloWorld *layer = HelloWorld::create();    // add layer as a child to scene    scene->addChild(layer);    // return the scene    return scene;}// on "init" you need to initialize your instancebool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !CCLayer::init() )    {        return false;    }        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();    /////////////////////////////    // 2. add a menu item with "X" image, which is clicked to quit the program    //    you may modify it.    // add a "close" icon to exit the progress. it's an autorelease object    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(                                        "CloseNormal.png",                                        "CloseSelected.png",                                        this,                                        menu_selector(HelloWorld::menuCloseCallback));    pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,                                origin.y + pCloseItem->getContentSize().height/2));    // create menu, it's an autorelease object    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);    pMenu->setPosition(CCPointZero);    this->addChild(pMenu, 1);    /////////////////////////////    // 3. add your codes below...    // add a label shows "Hello World"    // create and initialize a label        CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);        // position the label on the center of the screen    pLabel->setPosition(ccp(origin.x + visibleSize.width/2,                            origin.y + visibleSize.height - pLabel->getContentSize().height));    // add the label as a child to this layer    this->addChild(pLabel, 1);    // add "HelloWorld" splash screen"    CCSprite* pSprite = CCSprite::create("HelloWorld.png");    // position the sprite on the center of the screen    pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));    // add the sprite as a child to this layer    this->addChild(pSprite, 0);        return true;}void HelloWorld::menuCloseCallback(CCObject* pSender){//#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)//CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");//#else//    CCDirector::sharedDirector()->end();//#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)//    exit(0);//#endif//#endif// 创建进程pthread_t tid;pthread_create(&tid, NULL, thread_fun, NULL);}void *thread_fun(void *arg){Json::Value root;root["user"] = Json::Value("kaven");root["score"] = Json::Value(123);Json::FastWriter fast_writer;string str = fast_writer.write(root);ODSocket cSocket;cSocket.Init();cSocket.Create(AF_INET,SOCK_STREAM,0);cSocket.Connect("192.168.28.69",8888);char recvBuf[64] = "\0";cSocket.Send(str.c_str(), str.size(), 0);cSocket.Recv(recvBuf,64,0);printf("%s was recived from server!\n",recvBuf);cSocket.Close();cSocket.Clean();Json::Reader re;Json::Value ro;re.parse(recvBuf, ro);string st_user = ro["user"].asString();int int_score = ro["score"].asInt();return NULL;}






0 0