本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=167
最近做一个联网实时交互的游戏,游戏中需要使用socket保持长连接,来保证客户端与服务器端进行实时交互。以下贴出自己的一些代码:
因为socket通信部分需要使用多线程,整个流程如下:
1、首先起一个线程,来进行socket通信的连接
- intGameServer::connectThreadStart(){
-
-
- 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代码:
void*GameServer::connectSocket(void*args)
- {
- connect("192.168.1.2","3343");
- returnNULL;
- }
再此处进行socket连接,如果连接成功之后,将会通知主线程,连接已经成功,此处我们使用了cocos2dx高级开发教程中封装的MTNotificationQueue进行子线程向主线程的通信,如果你不了解,可以自己去百度
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("failedtocreatesocketn");
- return-1;
- }
- if(::connect(m_socketHandle,(sockaddr*)&sa,sizeof(sa))<0){
- printf("failedtoconnectsocketn");
- ::close(m_socketHandle);
- CCLOG("ClientconnectOK!IP:%s:%d",port);
- MTNotificationQueue::sharedNotificationQueue()->postNotification("connectok",NULL);
- return0;
- }
3、通知主线程之后,主线程将会负责开启新的线程进行recv监听,监听服务器下发的数据
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通信接收函数
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)
-
- rs=false;
- if(ret==4)
- buffer[4]=' ';
- 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:%sn",contents.c_str());
- CCString*str=CCString::create(Utils::getUnPackMsg(contents));
- MTNotificationQueue::sharedNotificationQueue()->postNotification("receivedata",str);
- CCLog("Error:recvdataError%d",ret);
- returnNULL;
- }
因为我们的cocos2dx客户端与服务器端约定,发送的前四个字节作为发送内容的字节长度,因此首先接收前四个字节,至此,一个多线程socket程序就完成了。
豌豆随心记 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|