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

cocos2dx socket 通信

发布时间:2020-12-14 16:33:43 所属栏目:百科 来源:网络整理
导读:本文由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代码:


    void*GameServer::connectSocket(void*args)
  1. {
  2. connect("192.168.1.2","3343");
  3. returnNULL;
  4. }

再此处进行socket连接,如果连接成功之后,将会通知主线程,连接已经成功,此处我们使用了cocos2dx高级开发教程中封装的MTNotificationQueue进行子线程向主线程的通信,如果你不了解,可以自己去百度

    intGameServer::connect(constchar*ip,unsignedintport)
  1. CCLOG("ClientbeginconnectIP:%s:%d",ip,port);
  2. structsockaddr_insa;
  3. structhostent*hp;
  4. hp=gethostbyname(ip);
  5. if(!hp){
  6. return-1;
  7. memset(&sa,153); font-weight:bold; background-color:inherit">sizeof(sa));
  8. memcpy((char*)&sa.sin_addr,hp->h_addr,hp->h_length);
  9. sa.sin_family=hp->h_addrtype;
  10. sa.sin_port=htons(port);
  11. m_socketHandle=socket(sa.sin_family,SOCK_STREAM,0);
  12. if(m_socketHandle<0){
  13. printf("failedtocreatesocketn");
  14. return-1;
  15. }
  16. if(::connect(m_socketHandle,(sockaddr*)&sa,sizeof(sa))<0){
  17. printf("failedtoconnectsocketn");
  18. ::close(m_socketHandle);
  19. CCLOG("ClientconnectOK!IP:%s:%d",port);
  20. MTNotificationQueue::sharedNotificationQueue()->postNotification("connectok",NULL);
  21. return0;
  22. }


3、通知主线程之后,主线程将会负责开启新的线程进行recv监听,监听服务器下发的数据

    voidGameServer::initReceiveThread(CCObject*obj)
  1. interrCode=0;
  2. }else{
  3. if(errCode==0){
  4. CCLOG("ReceiveThreadOK!!!");
  5. else{
  6. CCLOG("ReceiveThreadError!!!!");
  7. 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)
  1. bytebuffer[5];
  2. stringcontents;
  3. intret=0;
  4. //先接受4字节,获取服务返回长度
  5. boolrs=true;
  6. while(rs)
  7. {
  8. contents="";
  9. ret=recv(m_socketHandle,buffer,4,0);
  10. //服务器关闭
  11. if(ret==0)
  12. //CCLog("Error:serverclose");
  13. rs=false;
  14. if(ret==4)
  15. buffer[4]='';
  16. intpacketlen=Utils::bytes2int(buffer);
  17. CCLOG("packetlen%d",packetlen);
  18. charbuf[packetlen];
  19. intrets=0;
  20. while((ret=recv(m_socketHandle,buf,packetlen-rets,0))>0)
  21. contents.append(buf,ret);
  22. packetlen-=ret;
  23. if(packetlen<=0)
  24. break;
  25. CCLog("recvcontent:%sn",contents.c_str());
  26. CCString*str=CCString::create(Utils::getUnPackMsg(contents));
  27. MTNotificationQueue::sharedNotificationQueue()->postNotification("receivedata",str);
  28. CCLog("Error:recvdataError%d",ret);
  29. returnNULL;
  30. }



因为我们的cocos2dx客户端与服务器端约定,发送的前四个字节作为发送内容的字节长度,因此首先接收前四个字节,至此,一个多线程socket程序就完成了。

豌豆随心记

(编辑:李大同)

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

    推荐文章
      热点阅读