CocoSocket开源下载与编写经验分享
2014-05-22 14:24
260 查看
cocos2dx 3.1都出了,但依然没有发现与它原生的SOCKET支持,于是,这几天在家,手工撸了一个。
目前版本对IOS,ANDROID,WINDOWS支持良好。且为异步SOCKET,不需要再开任何线程。
特点
1、异步SOCKET,无需任何线程
2、只有一个头文件,使用方便
3、支持IOS,ANDROID,WINDOWS
下载连接 v0.0.1
下载连接 v0.0.2
示例:
各位可以尝试使用,若有什么坑,可以回复此贴,或者来信告诉我,一起完善,谢谢。 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 外面使用只需要这样。
class MyHandler:public ISocketHandler
{
.....实现方法
}
使用
CocoSocket socket;
MyHandler handler;
socket.setHandler(&handler);
socket.create(...);
socket.connect(....);
就OK了。
目前版本对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.\n"); } virtual void onConnectFailed() { printf("connect failed.\n"); } virtual void onMessage(const char* msg, int len) { printf("%s",msg); } virtual void onDisconnected() { printf("disconnected.\n"); } }; //使用 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 外面使用只需要这样。
class MyHandler:public ISocketHandler
{
.....实现方法
}
使用
CocoSocket socket;
MyHandler handler;
socket.setHandler(&handler);
socket.create(...);
socket.connect(....);
就OK了。
相关文章推荐
- 经验分享 |【PDF下载】阿里开源峰会之BeeHive:一种大型iOS项目解耦实践
- 经验分享 |【PDF下载】运维/DevOps峰会之开源DevOps工具云上自动运维
- 经验分享 | 【PDF下载】阿里开源峰会之AliSQL功能特性详解
- android4.4系统源码下载编译经验分享及总结(2014最新实践)
- 分享开发soket经验 我的基于socket的持久层 [转]
- 如何编写健壮的Bash脚本(经验分享)
- 移动开发经验分享1:IOS应用文件下载及打开
- 开源技术资料分享群-汇集各种开源资料、视频,欢迎大家学习下载
- 分享开发soket经验 我的基于socket的持久层
- 谷歌北京开发者社区开源Linux开发经验及典型应用案例分享讲座
- 谷歌北京开发者社区开源Linux开发经验及典型应用案例分享讲座
- 通用社区登陆组件技术分享(开源)下篇:OAuth 源码下载及原理解说
- 第一次编写max场景导出插件的经验分享(仅限第一次写max插件的兄弟姐妹)
- EntLib.com 开源电子商务系统v3.0 发布(源码和数据库)-分享下载!
- EntLib.com 开源电子商务系统v3.0 发布(源码和数据库)-分享下载!
- 开发者是如何提升技能水平的 发表于1小时前| 770次阅读| 来源SquareSpace| 1 条评论| 作者Denis Gobo 开源程序员博客代码编程经验分享 摘要:作为一个技术开发人员,不断的学
- C#编写的局域网聊天工具(本菜鸟刚学Socket,拿来分享下~~~)
- 通用社区登陆组件技术分享(开源)下篇:OAuth 源码下载及原理解说
- 如何编写健壮的Bash脚本(经验分享)
- 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载 推荐