最近網上查找資料並結合很久以前pc遊戲中使用的tcp/ip代碼,整理出cocos2d-x 跨平臺的客戶端網絡模塊
目前數據包仍是以前的字節碼數據形式,後續會修改使用protobuff的數據交換方式
(注:代碼未測試,先將內容記錄下來)
GlobalDef.h文件
#ifndef GLOBAL_DEF_HEAD_FILE
#define GLOBAL_DEF_HEAD_FILE
#pragma once
#include "cocos2d.h"
#include "utils/Utils.h"
#include "utils/TypeDef.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////
//常量定義
#define SERVER_ADDR "localhost"
#define SERVER_PORT 9010
/////////////////////////////////////////////////////////////////////////////////////////
//宏定義
//網絡數據定義
#define SOCKET_VER 65 //數據包版本
#define SOCKET_PACKAGE 2046 //最大網絡包
#define SOCKET_BUFFER (sizeof(CMD_Head)+SOCKET_PACKAGE+2*sizeof(DWORD))
//分配模式
#define DISTRIBUTE_MODE_NONE 0 //自由分配
#define DISTRIBUTE_MODE_RAND 1 //隨機分配
#define DISTRIBUTE_MODE_PLAN 2 //定位分配
/////////////////////////////////////////////////////////////////////////////////////////
//數據包結構信息
struct CMD_Info
{
WORD wDataSize; //數據大小
BYTE cbCheckCode; //效驗字段
BYTE cbMessageVer; //版本標識
};
//數據包命令信息
struct CMD_Command
{
WORD wMainCmdID; //主命令碼
WORD wSubCmdID; //子命令碼
};
//數據包傳遞包頭
struct CMD_Head
{
CMD_Info CmdInfo; //基礎結構
CMD_Command CommandInfo; //命令信息
};
//網絡數據包緩衝
struct CMD_Buffer
{
CMD_Head Head; //數據包頭
BYTE cbBuffer[SOCKET_PACKAGE]; //數據緩衝
};
//內核命令碼
#define MDM_KN_COMMAND 0 //內核命令
#define SUB_KN_DETECT_SOCKET 1 //檢測命令
//檢測結構信息
struct CMD_KN_DetectSocket
{
DWORD dwSendTickCount; //發送時間
DWORD dwRecvTickCount; //接收時間
};
/////////////////////////////////////////////////////////////////////////////////////////
//IPC 數據定義
#define IPC_VER 0x0001 //IPC 版本
#define IPC_IDENTIFIER 0x0001 //標識號碼
#define IPC_PACKAGE 4096 //最大 IPC 包
#define IPC_BUFFER (sizeof(IPC_Head)+IPC_PACKAGE) //緩衝長度
//IPC 數據包頭
struct IPC_Head
{
WORD wVersion; //IPC 版本
WORD wDataSize; //數據大小
WORD wMainCmdID; //主命令碼
WORD wSubCmdID; //子命令碼
};
//IPC 緩衝結構
struct IPC_Buffer
{
IPC_Head Head; //數據包頭
BYTE cbBuffer[IPC_PACKAGE]; //數據緩衝
};
//////////////////////////////////////////////////////////////////////////
//機器序列號結構
struct tagClientSerial
{
DWORD dwSystemVer; //系統版本
DWORD dwComputerID[3]; //機器序列
};
//配置緩衝結構
struct tagOptionBuffer
{
BYTE cbBufferLen; //數據長度
BYTE cbOptionBuf[32]; //設置緩衝
};
/////////////////////////////////////////////////////////////////////////////////////////
#endif
TypeDef.h
#ifndef TYPE_DEF_HEAD_FILE
#define TYPE_DEF_HEAD_FILE
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef int INT;
typedef unsigned int UINT;
#endif
Utils.h
#ifndef _UTILS_H__
#define _UTILS_H__
#include <iostream>
#include <vector>
#include <time.h>
#include "cocos2d.h"
USING_NS_CC;
using namespace std;
#define kMaxStringLen (1024*100)
class Utils
{
private:
Utils();
~Utils();
public:
static Utils* Instance();
//字符串操作
//字符分割
static vector<string> Split(string str,string pattern);
//判斷包含
static bool IsContantString(string sourceStr,string patternStr);
//格式化字符串
static string CCStringFormat(string format, ...);
//格式化字符串
static string CCStringFormat(const char* format, ...);
//轉爲小寫
static string ToLower(string str);
//轉爲大寫
static string ToUpper(string str);
//字符替換
static bool StringReplace(std::string& src, std::string target, std::string replacement);
//char to hex
static void Char2Hex(unsigned char ch, char* szHex);
//hex to char
static void Hex2Char(char const* szHex, unsigned char& rch);
//cahr string to hex tring
static void CharStr2HexStr(unsigned char const* pucCharStr, char* pszHexStr, int iSize);
//hex string to char string
static void HexStr2CharStr(char const* pszHexStr, unsigned char* pucCharStr, int iSize);
//系統相關
//獲取隨機數
static int Random(int start, int end);
//獲取當前時間毫秒
static long CurrentTimeInMS();
//獲取從1970年以來的時間
static double TimeIntervalSince1970();
//系統時間
static int64_t MillisecondNow();
//由時間戳獲取天數
static int GetDayByTime(time_t time);
//輔助函數
//清理vector內存
template < class T > static void VectorClear(vector< T >& vt)
{
vector< T > vectorTemp;
vectorTemp.swap( vt );
}
};
//雙擊判斷
static inline bool isDoubleTouch()
{
static long lastTouchTime=0;
long thisTouchTime= (long)Utils::MillisecondNow();
if(abs(thisTouchTime-lastTouchTime)<250)
{
lastTouchTime=0;
return true;
}
else
{
lastTouchTime= (long)Utils::MillisecondNow();
return false;
}
return false;
}
static inline string CCStringFormat(const char* format, ...)
{
string str;
va_list ap;
va_start(ap, format);
// bool bRet = false;
char* pBuf = (char*)malloc(kMaxStringLen);
memset(pBuf, 0, kMaxStringLen);
if (pBuf != NULL)
{
vsnprintf(pBuf, kMaxStringLen, format, ap);
str = pBuf;
free(pBuf);
// bRet = true;
}
va_end(ap);
return str;
}
static inline string CCStringFormat(string format, ...)
{
string str;
va_list ap;
va_start(ap, format);
// bool bRet = false;
char* pBuf = (char*)malloc(kMaxStringLen);
memset(pBuf, 0, kMaxStringLen);
if (pBuf != NULL)
{
vsnprintf(pBuf, kMaxStringLen, format.c_str(), ap);
str = pBuf;
free(pBuf);
// bRet = true;
}
va_end(ap);
return str;
}
static inline string CCStringWithInt(int value)
{
return CCStringFormat("%d", value);
}
#endif
Utils.cpp
#include "Utils.h"
Utils* Utils::Instance()
{
static Utils instance;
return &instance;
}
Utils::Utils()
{
srand((int)time(NULL));
}
Utils::~Utils(){
}
//c++字符串分割函數
vector<string> Utils::Split(string str,string pattern)
{
std::string::size_type pos;
std::vector<std::string> result;
str+=pattern;//擴展字符串以方便操作
long size=str.size();
for(long i=0; i<size; i++)
{
pos=str.find(pattern,i);
if(pos<size)
{
std::string s=str.substr(i,pos-i);
result.push_back(s);
i=pos+pattern.size()-1;
}
}
return result;
}
bool Utils::IsContantString(string sourceStr,string patternStr)
{
const char *show;
show = strstr(sourceStr.c_str(),patternStr.c_str());//返回指向第一次出現r位置的指針,如果沒找到則返回NULL。
bool isContant;
if (show == NULL)
{
isContant = false;
}
else
{
isContant = true;
}
return isContant;
}
string Utils::ToLower(string str)
{
std::string result(str.length(), 'X');
transform(str.begin(), str.end(), result.begin(), ::tolower);
return result;
}
string Utils::ToUpper(string str)
{
string result(str.length(), 'X');
transform(str.begin(), str.end(), result.begin(), ::toupper);
return result;
}
bool Utils::StringReplace(std::string& src, std::string target, std::string replacement)
{
std::string::size_type startpos = 0;
while (startpos!= std::string::npos)
{
startpos = src.find(target); //找到'.'的位置
if( startpos != std::string::npos ) //std::string::npos表示沒有找到該字符
{
src.replace(startpos,1,replacement); //實施替換,注意後面一定要用""引起來,表示字符串
}
}
return true;
}
//Function to convert unsigned char to string of length 2
void Utils::Char2Hex(unsigned char ch, char* szHex)
{
unsigned char byte[2];
byte[0] = ch/16;
byte[1] = ch%16;
for(int i=0; i<2; i++)
{
if(byte[i] >= 0 && byte[i] <= 9)
szHex[i] = '0' + byte[i];
else
szHex[i] = 'A' + byte[i] - 10;
}
szHex[2] = 0;
}
//Function to convert string of length 2 to unsigned char
void Utils::Hex2Char(char const* szHex, unsigned char& rch)
{
rch = 0;
for(int i=0; i<2; i++)
{
if(*(szHex + i) >='0' && *(szHex + i) <= '9')
rch = (rch << 4) + (*(szHex + i) - '0');
else if(*(szHex + i) >='A' && *(szHex + i) <= 'F')
rch = (rch << 4) + (*(szHex + i) - 'A' + 10);
else
break;
}
}
//Function to convert string of unsigned chars to string of chars
void Utils::CharStr2HexStr(unsigned char const* pucCharStr, char* pszHexStr, int iSize)
{
int i;
char szHex[3];
pszHexStr[0] = 0;
for(i=0; i<iSize; i++)
{
Char2Hex(pucCharStr[i], szHex);
strcat(pszHexStr, szHex);
}
}
//Function to convert string of chars to string of unsigned chars
void Utils::HexStr2CharStr(char const* pszHexStr, unsigned char* pucCharStr, int iSize)
{
int i;
unsigned char ch;
for(i=0; i<iSize; i++)
{
Hex2Char(pszHexStr+2*i, ch);
pucCharStr[i] = ch;
}
}
int Utils::Random(int start, int end)
{
float i = ((float)rand()/RAND_MAX)*(end-start+1)+start;
return (int)i;
return 0;
}
//得到系統啓動以後的毫秒級時間,然後除以CLOCKS_PER_SEC,就可以換成“秒”,標準c函數
long Utils::CurrentTimeInMS()
{
//獲取系統時鐘
clock_t t = clock();
long millisecond = t / 1000;
return millisecond;
}
//獲取1970.1.1後的毫秒數
double Utils::TimeIntervalSince1970()
{
time_t rawtime;
//輸入參數和返回值一致
time ( &rawtime );
return (double)rawtime;
}
int64_t Utils::MillisecondNow()
{
clock_t t = clock();
// long sec = t / CLOCKS_PER_SEC;
long millisecond = t / 1000;
return millisecond;
}
//由時間戳獲取天數
int Utils::GetDayByTime(time_t time)
{
struct tm tm;
tm = *localtime(&time);
int year = tm.tm_year;
int month = tm.tm_mon;
int day = tm.tm_mday;
int totalDay = year *365 + month *30 + day;
return totalDay;
}
QQ羣:239759131 cocos 技術交流 歡迎您