zoukankan      html  css  js  c++  java
  • CocoSocket开源下载与编写经验分享

    CocoSocket分享


    cocos2dx 3.1都出了,但依然没有发现与它原生的SOCKET支持,于是,这几天在家,手工撸了一个。

    目前版本对IOS,ANDROID,WINDOWS支持良好。且为异步SOCKET,不需要再开任何线程。

    特点
    1、异步SOCKET,无需任何线程
    2、只有一个头文件,使用方便
    3、支持IOS,ANDROID,WINDOWS

    下载连接 v0.0.1

    下载连接 v0.0.2

    示例:

    //自定义消息处理器
    class CSessionHandler :public ISocketHandler
    {
        virtual void onConnected()
        {
            printf("connected.
    ");
        }
    
        virtual void onConnectFailed()
        {
            printf("connect failed.
    ");
        }
    
        virtual void onMessage(const char* msg, int len)
        {
            printf("%s",msg);
        }
    
        virtual void onDisconnected()
        {
            printf("disconnected.
    ");
        }
    };
    
    //使用
    CSessionHandler oo;
    CocoSocket cSocket;
    cSocket.setHandler(&oo);
    cSocket.create(AF_INET, SOCK_STREAM, 0);
    cSocket.connect("192.168.1.7", 8643);

    各位可以尝试使用,若有什么坑,可以回复此贴,或者来信告诉我,一起完善,谢谢。 GMAIL:boyuegame

    遇上的问题


    由于对socket和select不是太熟悉,那先说说遇上的坑吧。

    1、WINDOWS上的返回错误码与IOS,ANDROID不一样。

    这才是最坑爹的,因此,不得不重新定义。 好在每一种返回,表示OK的就那一个两个,其它都无视,还算好搞。

    2、非阻塞的SOCKET在进行connect的时候,成功与失败的判定问题

    POSIX有一个规则,就是当connect成功的时候, 可写,当connect失败的时候,即可读又可写。 

    但这并不能作为判定标准,因为当SOCKET连接成功,服务器有数据过来的时候,也会变成即可读,又可写。 

    WINDOWS下并没有遵守这个规则, 通过MSDN的查看,才发现,在WDINWOS上,当connect连接成功时,可写,当连接失败时,是通过fd_set* error返回的。 因此,在WINDOWS上就很容易处理。

    那在LINUX和MAC下如何呢。 LINUX和UNIX的 MAN PAGE上介绍是通过getsocketopt的返回值才判定。 还有一种是尝试再次connect,看是否返回值为EISCONN来判定。 网上有一篇贴子说这在LINUX下不靠谱,所以我就没有尝试。

    转而,使用另一个规则。 

    不管是connect成功还是失败,总是可写的。所以,当可写的时候,我们尝试从缓冲区里read 0字节,如果返回值为0,则表示连接成功,如果返回-1,那肯定就是连接失败了。 这个在IOS和ANDROID下工作良好。

    3、网上很多人说 recv(fd,buf,buf_len,MSG_NOSIGNAL)可以防止SIGPIPE信号的产生

    这简直就是放屁,看看最后一个参数的意思吧。

    4、如何正确忽略SIGPIPE信号

    struct sigaction sa;
    sa.sa_handler = SIG_IGN;
    sa.sa_flags = 0;
    if (sigemptyset(&sa.sa_mask) == -1 ||
        sigaction(SIGPIPE, &sa, 0) == -1) 
        {
            perror("failed to ignore SIGPIPE; sigaction");
            exit(EXIT_FAILURE);
        }
    }

    由于在WINDOWS上,要进行SOCKET SETUP,在ANDOIRD,IOS上,要进行SIGPIPE忽略,所以我弄了一个SocketPrepare类,当有SOCKET初始化的时候,构造一个静态对象,比较方便。 避免CPP依赖,所有东西,都放到了.H里。

    5、ANDROID

     ANDROID上面,检测是否连接成功,还是得用getsockopt,但连接失败的检查不是太容易。 

    新增的超时检查,可以用于任意平台的连接失败检查。毕竟游戏里面,都是会做连接超时的。

    由于我希望外面使用干净,所以,我使用了cocos的shcedule来调度事件检测,这样就隐藏了Reactor 外面使用只需要这样。

    //实现自己的消息Handler
    class MyHandler:public ISocketHandler
    {
        //实现方法
    }
    
    
    //如何使用
    //实例化一个CocoSocket
    CocoSocket socket;
    //实例化一个Handler
    MyHandler handler;
    //绑定
    socket.setHandler(&handler);
    //分配Socket系统资源
    socket.create(...);
    //连接目标地址
    socket.connect(....);

    结术语


    无。

  • 相关阅读:
    JDK8:Lambda表达式
    静态代理模式
    javaEE servlet tomcat jsp对应关系
    cmake 实现交叉编译注意事项
    vector 初始化
    今儿谈谈:互联网创业公司,CTO,CFO,CEO们各负责什么?
    解答网友问:继续学习计算机还是转成会计专业!?如何做正确选择!
    谈谈关于男孩子学会计什么样?有没有发展钱途!
    代码时代!码农所创造财务机器人是财务人的解药还是毒药!?
    谈谈关于人工智能对财务会计行业的影响
  • 原文地址:https://www.cnblogs.com/qilinzi/p/3745561.html
Copyright © 2011-2022 走看看