2. 接口分析分析C源码,KCP作为中间管理层,主要提供以下接口
//---------------------------------------------------------------------// interface//---------------------------------------------------------------------// create a new kcp control object, 'conv' must equal in two endpoint// from the same connection. 'user' will be passed to the output callback// output callback can be setup like this: 'kcp->output = my_udp_output'// 创建kcp对象,conv必须在两个端之间相同,user会被传递到output回调,// output回调这样设置:kcp->output = my_udp_outputikcpcb* ikcp_create(IUINT32 conv, void *user);// release kcp control object// 释放kcp对象void ikcp_release(ikcpcb *kcp);// set output callback, which will be invoked by kcp// 设置kcp调用的output回调void ikcp_setoutput(ikcpcb *kcp, int (*output)(const char *buf, int len,ikcpcb *kcp, void *user));// user/upper level recv: returns size, returns below zero for EAGAIN// 用户层/上层 接收消息:返回接收长度,数据读取错误返回值小于0int ikcp_recv(ikcpcb *kcp, char *buffer, int len);// user/upper level send, returns below zero for error// 用户层/上层 发送消息,错误返回值小于0int ikcp_send(ikcpcb *kcp, const char *buffer, int len);// update state (call it repeatedly, every 10ms-100ms), or you can ask // ikcp_check when to call it again (without ikcp_input/_send calling).// 'current' - current timestamp in millisec. // 更新状态(每10ms-100ms调用一次),或者你可以通过调用ikcp_check,// 来得知什么时候再次调用(不调用ikcp_input/_send)// current - 当前时间戳(毫秒)void ikcp_update(ikcpcb *kcp, IUINT32 current);// Determine when should you invoke ikcp_update:// returns when you should invoke ikcp_update in millisec, if there // is no ikcp_input/_send calling. you can call ikcp_update in that// time, instead of call update repeatly.// Important to reduce unnacessary ikcp_update invoking. use it to // schedule ikcp_update (eg. implementing an epoll-like mechanism, // or optimize ikcp_update when handling massive kcp connections)// 决定你什么时候调用ikcp_update// 返回你多少毫秒后应该调用ikcp_update,如果没有ikcp_input/_send调用,你可以在那个时间// 调用ikcp_updates来代替自己驱动update调用// 用于减少不必要的ikcp_update调用 。用这个来驱动ikcp_update(比如:实现类epoll的机制,// 或者优化处理大量kcp连接时的ikcp_update调用)IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current);// when you received a low level packet (eg. UDP packet), call it// 接收下层数据包(比如:UDP数据包)时调用int ikcp_input(ikcpcb *kcp, const char *data, long size);// flush pending data// 刷新数据void ikcp_flush(ikcpcb *kcp);// check the size of next message in the recv queue// 检测接收队列里下条消息的长度int ikcp_peeksize(const ikcpcb *kcp);// change MTU size, default is 1400// 修改MTU长度,默认1400int ikcp_setmtu(ikcpcb *kcp, int mtu);// set maximum window size: sndwnd=32, rcvwnd=32 by default// 设置最大窗口大小,默认值:sndwnd=32, rcvwnd=32int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);// get how many packet is waiting to be sent// 获取准备发送的数据包int ikcp_waitsnd(const ikcpcb *kcp);// fastest: ikcp_nodelay(kcp, 1, 20, 2, 1)// nodelay: 0:disable(default), 1:enable// interval: internal update timer interval in millisec, default is 100ms // resend: 0:disable fast resend(default), 1:enable fast resend// nc: 0:normal congestion control(default), 1:disable congestion control// 快速设置:ikcp_nodelay(kcp, 1, 20, 2, 1)// nodelay:0:使用(默认),1:使用// interval:update时间(毫秒),默认100ms// resend:0:不适用快速重发(默认), 其他:自己设置值,若设置为2(则2次ACK跨越将会直接重传)// nc:0:正常拥塞控制(默认), 1:不适用拥塞控制int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc);void ikcp_log(ikcpcb *kcp, int mask, const char *fmt, ...);// setup allocator// 设置kcp allocatorvoid ikcp_allocator(void* (*new_malloc)(size_t), void (*new_free)(void*));// read conv// 获取convIUINT32 ikcp_getconv(const void *ptr);3. 调度逻辑

文章插图
KCP关键接口:
- 更新(上层驱动KCP状态更新)
ikcp_update:kcp状态更新接口,需要上层进行调度,判断flush时间,满足条件调用ikcp_flush刷新数据,同时也负责对收到数据的kcp端回复ACK消息 - 发送
ikcp_send -> ikcp_update -> ikcp_output ikcp_send:上层调用发送接口,把数据根据mss值进行分片,设置分包编号,放到snd_queue队尾 ikcp_flush:发送数据接口,根据对端窗口大小,拷贝snd_queue的数据到snd_buf,遍历snd_buf,满足条件则调用output回调(调用网络层的发送)
推荐阅读
- 中国茶叶十大排名看看有没有你认识的
- 如何让你的大iPhone更舒适地单手使用
- “三”大方向,构筑5G下一站:中国移动张晓然详解R18标准演进
- 硅胶模具可以用热水烫吗 雪糕模具硅胶的使用前要用热水烫吗
- 好的茶叶多少钱斤 价格影响因素
- 笑傲江湖中小尼姑叫什么名字 笑傲江湖的小尼姑叫什么
- 感应水龙头原理 感应水龙头使用注意事项
- 杭州拟为保护西湖龙井茶立法,违规使用专用标识最高罚五万
- 杭州集中打击假冒“西湖龙井”:案值逾七千万,抓83人
- 茶叶蛋的做法放的什么茶叶
