本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=167
最近做一个联网实时交互的游戏,游戏中需要使用socket保持长连接,来保证客户端与服务器端进行实时交互。以下贴出自己的一些代码:
因为socket通信部分需要使用多线程,整个流程如下:
1、首先起一个线程,来进行socket通信的连接
- intGameServer::connectThreadStart(){
- //connect(GAMESERVER,CCString::create(GAMESERVER_PORT)->intValue());
- interrCode=0;
- do{
- pthread_attr_ttAttr;
- errCode=pthread_attr_init(&tAttr);
- CC_BREAK_IF(errCode!=0);
- errCode=pthread_attr_setdetachstate(&tAttr,PTHREAD_CREATE_DETACHED);
- if(errCode!=0){
- pthread_attr_destroy(&tAttr);
- break;
- }
- errCode=pthread_create(&m_gameThread,&tAttr,connectSocket,this);
- }while(0);
- returnerrCode;
- }
2、连接socket代码:
再此处进行socket连接,如果连接成功之后,将会通知主线程,连接已经成功,此处我们使用了cocos2dx高级开发教程中封装的MTNotificationQueue进行子线程向主线程的通信,如果你不了解,可以自己去百度
copy
intGameServer::connect(constchar*ip,unsignedintport)
CCLOG("ClientbeginconnectIP:%s:%d",ip,port);
structsockaddr_insa;
structhostent*hp;
hp=gethostbyname(ip);
if(!hp){
return-1;
memset(&sa,153); font-weight:bold; background-color:inherit">sizeof(sa));
memcpy((char*)&sa.sin_addr,hp->h_addr,hp->h_length);
sa.sin_family=hp->h_addrtype;
sa.sin_port=htons(port);
m_socketHandle=socket(sa.sin_family,SOCK_STREAM,0);
if(m_socketHandle<0){
printf("failedtocreatesocket\n");
return-1;
}
if(::connect(m_socketHandle,(sockaddr*)&sa,sizeof(sa))<0){
printf("failedtoconnectsocket\n");
::close(m_socketHandle);
CCLOG("ClientconnectOK!IP:%s:%d",port);
MTNotificationQueue::sharedNotificationQueue()->postNotification("connectok",NULL);
return0;
}
3、通知主线程之后,主线程将会负责开启新的线程进行recv监听,监听服务器下发的数据
copy
voidGameServer::initReceiveThread(CCObject*obj)
interrCode=0;
}else{
if(errCode==0){
CCLOG("ReceiveThreadOK!!!");
else{
CCLOG("ReceiveThreadError!!!!");
MTNotificationQueue::sharedNotificationQueue()->postNotification("jointable",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> }
开启socket通信接收函数
copy
void*GameServer::listenSocketData(void*obj)
bytebuffer[5];
stringcontents;
intret=0;
//先接受4字节,获取服务返回长度
boolrs=true;
while(rs)
{
contents="";
ret=recv(m_socketHandle,buffer,4,0);
//服务器关闭
if(ret==0)
//CCLog("Error:serverclose");
rs=false;
if(ret==4)
buffer[4]='\0';
intpacketlen=Utils::bytes2int(buffer);
CCLOG("packetlen%d",packetlen);
charbuf[packetlen];
intrets=0;
while((ret=recv(m_socketHandle,buf,packetlen-rets,0))>0)
contents.append(buf,ret);
packetlen-=ret;
if(packetlen<=0)
break;
CCLog("recvcontent:%s\n",contents.c_str());
CCString*str=CCString::create(Utils::getUnPackMsg(contents));
MTNotificationQueue::sharedNotificationQueue()->postNotification("receivedata",str);
CCLog("Error:recvdataError%d",ret);
returnNULL;
}
因为我们的cocos2dx客户端与服务器端约定,发送的前四个字节作为发送内容的字节长度,因此首先接收前四个字节,至此,一个多线程socket程序就完成了。
原文链接:/cocos2dx/340287.html