IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> ascs 简明开发教程(二十二):可靠的UDP传输 -> 正文阅读

[网络协议]ascs 简明开发教程(二十二):可靠的UDP传输

QQ交流群:198941541

可靠UDP基于KCP(https://github.com/skywind3000/kcp),用户需要熟悉KCP的窗口大小,重传模式,流控等,ascs还是原来的的原则,不封装KCP,用户通过ikcpcb* get_kcpcb() 得到ikcpcb做任意想要的配置,当然应该在数据收发之前(构造函数里面和reset虚函数里面,后者会在socket被重用之后马上被调用)。

reliable_socket_base继承自原来的 UDP socket_base,所以如果你不创建KCP(create_kcpcb),可靠UDP会退化成普通的UDP,参考udp_test。

使用可靠UDP需要用户提供一个回调函数,签名为:int output(const char* buf, int len, ikcpcb * kcp, void* user),不支持仿函数(因为KCP是纯C的),由于ascs是header only的,我很难去提供这么一个函数而不造成重复定义,如果定义成inline或者static,那么编译得到的所有.o文件里面都将有一份实现,即使不造成重复定义也不好,如果大家有更好的办法,欢迎群里面讨论。用户在这个回调函数里面直接调用reliable_socket_base的output函数即可,无需考虑多线程安全的问题,参考udp_test。这个回调函数通过KCP函数ikcp_setoutput送给ikcpcb(如果没有这一步,编译无法检测但程序会core dump),ikcpcb通过reliable_socket_base::get_kcpcb() 得到,当然这之前你必须已经调用过reliable_socket_base::create_kcpcb 创建了ikcpcb了。

可靠UDP,需要用宏ASCS_RELIABLE_UDP_NSND_QUE或者set_max_nsnd_que设置一个发送队列大小(消息条数)上限,这是因为KCP的缓存大小是无限的,所以我们必需要在必要时限速,当KCP的发送队列消息数量大于这个值之后,ascs将暂停向其输送(ikcp_send)新的消息,此时消息会停在ascs的发送缓存里面,而ascs的发送缓存也是有限制,这样最终将造成用户调用send_msg失败。

KCP也没有解决的问题——连接重置:

在决定用KCP之前,我也想过自己开发一个可靠UDP,但就是这个连接重置难倒了我,后来在群里朋友的推荐下,采用了KCP。不管谁来实现可靠UDP,总是会有缓存来解决消息丢失,消息重复,消息乱序等问题,所以缓存是很复杂的,那如果通信双方一方重启了,接收方可能会永远接收不到某个消息,那么这个消息之后的消息,即便是收到了,也不能派发出来(否则消息乱序),那么对于这种无法恢复的问题(或者设定时间内无法解决的问题),我们需要重置连接,意思是通信双方从这一刻开始重新来过,过往的所有错误既往不咎,可惜这种自动连接重置很难实现,只能在业务层上来做。我推荐的做法是,再建一条TCP连接,专门用于通知这种连接重置,一方出问题恢复之后,通过TCP告诉对方,并协商一个新的conv(可以与之前的一样,也可以不一样,总之通信双方用相同的conv即可,conv用于创建ikcpcb,参考reliable_socket_base::create_kcpcb),然后双方开始重新创建新的ikcpcb,这样可靠UDP又可以工作了。

注意你不能随时调用reliable_socket_base::create_kcpcb,必须先关闭socket(force_shutdown等),对于single_reliable_socket_service,如果你想重用它,等到after_close被调用之后,你就可以调用reliable_socket_base::create_kcpcb重新创建ikcpcb了,然后调用start(或者service_pump带i_service的start_service)再次启用它,其实最简单的办法还是创建一个新的single_reliable_socket_service;对于multi_reliable_socket_service,你调用其add_socket得到socket之后(虽然叫add,其实可能的话也是会重用的,并不一定是add,如果是重用,object_pool会先调用socket的reset,再返回socket,然后add_socket再返回给你),就可以调用reliable_socket_base::create_kcpcb重新创建ikcpcb了。

在socket的on_close里面,会释放ikcpcb,所以被关闭了的socket,如果要重用,一定要重新创建ikcpcb。

上一篇?ascs 简明开发教程(21)

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-05 11:23:21  更:2021-09-05 11:24:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/14 19:32:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码