有小段时间没写blog了,今儿就说说socketcc的使用。当然和socket配套的线程也会提及,弄socket以及线程pthread时间几乎是新手,所以不对或者要改进的地方请过客多多提及以及修正。
ok。开始先说pthread这个c线程的东西。其实使用方法非常简单:
pthread_t pthread_initSocket,
if ((pthread_create(&pthread_initSocket, NULL, initSocketAndSendData, NULL)) != 0) assert("创建initSocketAndSendData线程失败!");
其中staticvoid* initSocketAndSendData(void* pthread);
就这样 线程跑起来了 所有的动作在initSocketAndSendData完成
接下来是socketcc:
TCPClientSocket* m_socket
//=====================================//
try
{
IPAddress address;
address.SetHostName(serverIp, false);
m_socket = newTCPClientSocket(address,serverPort);
// 设置超时
//structtimeval timeout;
//socklen_t len = sizeof(timeout);
//timeout.tv_sec = OVER_TIME;
//m_socket -> SetSockOpt(SOL_SOCKET, SO_RCVTIMEO, &timeout, len);
cocos2d::CCLog(" - Name : %s\n", (constchar *) address);
cocos2d::CCLog(" - Family : %s\n", (address.GetAddressFamily() == AF_INET6)?"IPv6":
((address.GetAddressFamily() == AF_INET)?"IPv4":"Unknown"));
cocos2d::CCLog(" - Address : %s\n", address.GetAddressString());
} catch (SocketException &excep)
{
cocos2d::CCLog("Socket Exception : %s\n\n", (constchar *) excep);
}
catch (...)
{
cocos2d::CCLog("Other Error\n\n");
}
// socket连接成功
/*创建接收数据的线程*/
if((pthread_create(&pthread_rec, NULL, reciveData, NULL)) != 0) assert("创建线程reciveData失败!");
//==================================//
void* reciveData(void *pth)
{
while (1)
{
CCLog("reciveData");
unsignedchar pcRecvBuf[MAX_RECV_SIZE];
try
{
int iBytesRec = m_socket -> RecvData(pcRecvBuf, MAX_RECV_SIZE);
CCLog("Received %d bytes of data\n", iBytesRec);
pcRecvBuf[iBytesRec] = 0;
//TODO 处理收到的数据
}catch(SocketException &excep)
{
cocos2d::CCLog("recvDatas Error: %s \n\n",(constchar*)excep);
} catch (...)
{
cocos2d::CCLog("recvDatas Error\n\n");
}
}
cocos2d::CCLog("net disconnect \n\n");
}
非 常 非常要注意 采用二进制网络字节接收到的数据非常很有可能一次是不全的 需要两边定义每次发送的数据包的长度 比如每个包的前4个字节int 数据包长度,然后接收的时候 小于4个就存起来 然后收到的每一个包就一直累加包的长度,当长度等于了这个有效包的长度的时候就表示包是完整的 就可以接着处理服务端的数据鸟,关于包的问题,如果是用二进制网络字节来收发就看前面的《c java通信并且实现以java为 准的网络字节转换》就是所谓的unsigned char*数组处理二进制模式的通信,当然你可以收发string类型的封装包比如xml的或者json类型或者自己定义的类型(比如用"."来区分每个 参数接收发送的时候自己封装前提是你的包永远不会出现"."的其他使用)的string。在发送string的时候,记得在最后要添加"./r /n"or"/n"否则貌似会有无法接收到包 是因为这个符号是表示string包的结束标志,实际上是使用readbuff有个readline方法引起的。