加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx socket 通信

发布时间:2020-12-14 16:52:50 所属栏目:百科 来源:网络整理
导读:本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=167 最近做一个联网实时交互的游戏,游戏中需要使用socket保持长连接,来保证客户端与服务器端进行实时交互。以下贴出自己的一些代码: 因为socket通信部分需要使用多线程,整个流程如下: 1

本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=167


最近做一个联网实时交互的游戏,游戏中需要使用socket保持长连接,来保证客户端与服务器端进行实时交互。以下贴出自己的一些代码:

因为socket通信部分需要使用多线程,整个流程如下:

1、首先起一个线程,来进行socket通信的连接

[cpp] view plain copy
  1. intGameServer::connectThreadStart(){
  2. //connect(GAMESERVER,CCString::create(GAMESERVER_PORT)->intValue());
  3. interrCode=0;
  4. do{
  5. pthread_attr_ttAttr;
  6. errCode=pthread_attr_init(&tAttr);
  7. CC_BREAK_IF(errCode!=0);
  8. errCode=pthread_attr_setdetachstate(&tAttr,PTHREAD_CREATE_DETACHED);
  9. if(errCode!=0){
  10. pthread_attr_destroy(&tAttr);
  11. break;
  12. }
  13. errCode=pthread_create(&m_gameThread,&tAttr,connectSocket,this);
  14. }while(0);
  15. returnerrCode;
  16. }


2、连接socket代码:


copy
void*GameServer::connectSocket(void*args)
  • {
  • connect("192.168.1.2","3343");
  • returnNULL;
  • }

  • 再此处进行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("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监听,监听服务器下发的数据

    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]='';
  • 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程序就完成了。

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读