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 int socklen_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 int SOCKET;
//#pragma region define win32 const variable in linux
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
//#pragma endregion
#endif
class ODSocket {
public:
ODSocket(SOCKET sock = INVALID_SOCKET);
~ODSocket();
// Create socket object for snd/recv data
bool Create(int af, int type, int protocol = 0);
// Connect socket
bool Connect(const char* ip, unsigned short port);
//#region server
// Bind socket
bool Bind(unsigned short port);
// Listen socket
bool Listen(int backlog = 5);
// Accept socket
bool Accept(ODSocket& s, char* fromip = NULL);
//#endregion
// Send socket
int Send(const char* buf, int len, int flags = 0);
// Recv socket
int Recv(char* buf, int len, int flags = 0);
// Close socket
int Close();
// Get errno
int GetError();
//#pragma region just for win32
// Init winsock DLL
static int Init();
// Clean winsock DLL
static int Clean();
//#pragma endregion
// Domain parse
static 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")
#endif
ODSocket::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).aspx
typedef struct WSAData {
WORD wVersion; //winsock version
WORD wHighVersion; //The highest version of the Windows Sockets specification that the Ws2_32.dll can support
char 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 up
if ( ret ) {
// cerr << "Initilize winsock error !" << endl;
return -1;
}
#endif
return 0;
}
//this is just for windows
int ODSocket::Clean()
{
#ifdef WIN32
return (WSACleanup());
#endif
return 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 server
bool 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 WIN32
return (closesocket(m_sock));
#else
return (close(m_sock));
#endif
}
int ODSocket::GetError()
{
#ifdef WIN32
return (WSAGetLastError());
#else
return (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.youkuaiyun.com/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 instance
bool 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;
}