mirror of https://github.com/F-Stack/f-stack.git
411 lines
14 KiB
C++
411 lines
14 KiB
C++
|
||
/**
|
||
* Tencent is pleased to support the open source community by making MSEC available.
|
||
*
|
||
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
||
*
|
||
* Licensed under the GNU General Public License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License. You may
|
||
* obtain a copy of the License at
|
||
*
|
||
* https://opensource.org/licenses/GPL-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||
* either express or implied. See the License for the specific language governing permissions
|
||
* and limitations under the License.
|
||
*/
|
||
|
||
|
||
/**
|
||
* @filename mt_api.h
|
||
* @info 微线程封装系统api, 同步调用微线程API,实现异步调度
|
||
*/
|
||
|
||
#ifndef __MT_API_H__
|
||
#define __MT_API_H__
|
||
|
||
#include <netinet/in.h>
|
||
#include <vector>
|
||
|
||
using std::vector;
|
||
|
||
namespace NS_MICRO_THREAD {
|
||
|
||
/******************************************************************************/
|
||
/* 微线程用户接口定义: UDP短连接收发接口 */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief 采用随机端口的socket收发接口, 由socket来决定上下文, 业务来保证上下文
|
||
* [注意] UDP发送buff, 不推荐static变量, 有一定风险导致上下文错乱[重要]
|
||
* @param dst -请求发送的目的地址
|
||
* @param pkg -请求包封装的包体
|
||
* @param len -请求包封装的包体长度
|
||
* @param rcv_buf -接收应答包的buff
|
||
* @param buf_size -modify-接收应答包的buff大小, 成功返回时, 修改为应答包长度
|
||
* @param timeout -超时时间, 单位ms
|
||
* @return 0 成功, -1 打开socket失败, -2 发送请求失败, -3 接收应答失败, 可打印errno
|
||
*/
|
||
int mt_udpsendrcv(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int& buf_size, int timeout);
|
||
|
||
|
||
/******************************************************************************/
|
||
/* 微线程用户接口定义: TCP连接池收发接口 */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief TCP检测报文是否接收完整的回调函数定义
|
||
* @param buf 报文保存缓冲区
|
||
* @param len 已经接收的长度
|
||
* @return >0 实际的报文长度; 0 还需要等待接收; <0 报文异常
|
||
*/
|
||
typedef int (*MtFuncTcpMsgLen)(void* buf, int len);
|
||
|
||
/**
|
||
* @brief TCP会采用连接池的方式复用IP/PORT连接, 连接保持默认10分钟
|
||
* [注意] tcp接收发送buff, 不可以是static变量, 否则会上下文错乱 [重要]
|
||
* @param dst -请求发送的目的地址
|
||
* @param pkg -请求包封装的包体
|
||
* @param len -请求包封装的包体长度
|
||
* @param rcv_buf -接收应答包的buff
|
||
* @param buf_size -modify-接收应答包的buff大小, 成功返回时, 修改为应答包长度
|
||
* @param timeout -超时时间, 单位ms
|
||
* @param check_func -检测报文是否成功到达函数
|
||
* @return 0 成功, -1 打开socket失败, -2 发送请求失败, -3 接收应答失败,
|
||
* -4 连接失败, -5 检测报文失败, -6 接收空间不够, -7 后端主动关闭连接,-10 参数无效
|
||
*/
|
||
int mt_tcpsendrcv(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int& buf_size,
|
||
int timeout, MtFuncTcpMsgLen chek_func);
|
||
|
||
|
||
enum MT_TCP_CONN_TYPE
|
||
{
|
||
MT_TCP_SHORT = 1, /// 短连接
|
||
MT_TCP_LONG = 2, /// 长连接
|
||
MT_TCP_SHORT_SNDONLY = 3, /// 短连接只发
|
||
MT_TCP_LONG_SNDONLY = 4, /// 长连接只发
|
||
MT_TCP_BUTT
|
||
};
|
||
|
||
/**
|
||
* @brief TCP收发接口,可以选择后端保持连接或者短连接
|
||
* [注意] tcp接收发送buff, 不可以是static变量, 否则会上下文错乱 [重要]
|
||
* @param dst -请求发送的目的地址
|
||
* @param pkg -请求包封装的包体
|
||
* @param len -请求包封装的包体长度
|
||
* @param rcv_buf -接收应答包的buff,只发不收可以设置为NULL
|
||
* @param buf_size -modify-接收应答包的buff大小, 成功返回时, 修改为应答包长度,只发不收,设置为NULL
|
||
* @param timeout -超时时间, 单位ms
|
||
* @param check_func -检测报文是否成功到达函数
|
||
* @param type - 连接类型
|
||
* MT_TCP_SHORT: 一收一发短连接;
|
||
* MT_TCP_LONG : 一发一收长连接;
|
||
* MT_TCP_LONG_SNDONLY : 只发不收长连接;
|
||
* MT_TCP_SHORT_SNDONLY: 只发不收短连接;
|
||
* @return 0 成功, -1 打开socket失败, -2 发送请求失败, -3 接收应答失败,
|
||
* -4 连接失败, -5 检测报文失败, -6 接收空间不够, -7 后端主动关闭连接, -10 参数无效
|
||
*/
|
||
int mt_tcpsendrcv_ex(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int* buf_size,
|
||
int timeout, MtFuncTcpMsgLen func, MT_TCP_CONN_TYPE type = MT_TCP_LONG);
|
||
|
||
/**
|
||
* @brief TCP检测报文是否接收完整的回调函数
|
||
* @param buf 报文保存缓冲区
|
||
* @param len 已经接收的长度
|
||
* @param closed 远端关闭连接,兼容通过链接关闭来确定报文长度的业务
|
||
* @param msg_ctx 解析报文的上下文变量。通过该值,业务可以实现报文解析状态机等,避免重复检查
|
||
* 业务在mt_tcpsendrcv中传入该参数,框架回调时传递给业务。该变量可以为类或者结构体,业务自定义。
|
||
* 报文解析结果,保存在变量中,mt_tcpsendrcv返回后,直接使用
|
||
* 【注意】 该回调函数传入的buf指针可能变化,所以报文解析状态机相关位置信息请使用偏移量
|
||
* @param msg_len_detected 传出参数 如果业务确定了报文长度,则将其设置为true,否则为false。传入时为false。
|
||
* 【注意】如果该值返回true,框架以函数返回值作为报文长度(>0)持续收包,在收包完成前,不再调用该MtFuncTcpMsgChecker函数;报文接收完成后,调用MtFuncTcpMsgChecker函数检查一次报文。减少因零碎收包引起的无效调用。
|
||
* @return >0 建议的接收缓冲大小; 0 还需要等待接收; <0 报文异常
|
||
* 【注意】
|
||
* 以下两种情况可以返回大于0:
|
||
* 1,业务确定报文长度,返回报文长度
|
||
* 2,业务不确定报文长度,给出接收buf的建议长度,如果长度大于现有buf长度,框架根据该值realloc buf。
|
||
*
|
||
* 返回值为0,表示业务无法确定报文长度,需要接续接收。如果buf收满,框架将realloc buf,buf大小扩大一倍
|
||
* 返回值小于0,表示业务确定报文错误
|
||
*/
|
||
typedef int (*MtFuncTcpMsgChecker)(void* buf, int len, bool closed, void* msg_ctx, bool &msg_len_detected);
|
||
|
||
|
||
|
||
/**
|
||
* @brief TCP收发接口,可以选择后端保持连接或者短连接
|
||
* [注意] tcp接收发送buff, 不可以是static变量, 否则会上下文错乱 [重要]
|
||
* @param dst -请求发送的目的地址
|
||
* @param pkg -请求包封装的包体
|
||
* @param len -请求包封装的包体长度
|
||
* @param rcv_buf -【传出参数】,参考参数 keep_rcv_buf。业务不需要malloc该内存。void* rcv_buf=NULL: 传给框架即可
|
||
* @param recv_pkg_size -接收应答包的buff的初始大小。函数返回0时,返回报文实际长度。
|
||
* @param timeout -超时时间, 单位ms
|
||
* @param check_func -检测报文是否成功到达函数
|
||
* @param msg_ctx -解析报文的上下文变量。
|
||
*
|
||
* @param type - 连接类型
|
||
* MT_TCP_SHORT: 一收一发短连接;
|
||
* MT_TCP_LONG : 一发一收长连接;
|
||
* MT_TCP_LONG_SNDONLY : 只发不收长连接;
|
||
* MT_TCP_SHORT_SNDONLY: 只发不收短连接;
|
||
* @param keep_rcv_buf -true,调用成功后,框架将最后的rcv_buf赋值给传出参数,业务负责释放该buf。否则框架在调用结束前释放该buf。【注意】
|
||
* 业务需要自己在msg_ctx中保留相关信息。【框架通过malloc申请内存】 默认框架自动释放该buf,业务需要在ctx保存信息
|
||
* @return 0 成功, -1 打开socket失败, -2 发送请求失败, -3 接收应答失败,
|
||
* -4 连接失败, -5 检测报文失败, -6 接收空间不够, -7 后端主动关闭连接, -10 参数无效, -11,申请接收buf失败
|
||
*/
|
||
int mt_tcpsendrcv_ex(struct sockaddr_in* dst, void* pkg, int len, void*& rcv_buf, int& recv_pkg_size,
|
||
int timeout, MtFuncTcpMsgChecker check_func, void* msg_ctx=NULL,
|
||
MT_TCP_CONN_TYPE type = MT_TCP_LONG, bool keep_rcv_buf=false);
|
||
|
||
/**
|
||
* @brief TCP会采用连接池的方式复用IP/PORT连接, 连接保持默认10分钟
|
||
* [注意] tcp接收发送buff, 不可以是static变量, 否则会上下文错乱 [重要]
|
||
* @param dst -请求发送的目的地址
|
||
* @param pkg -请求包封装的包体
|
||
* @param len -请求包封装的包体长度
|
||
* @param rcv_buf -【传出参数】,参考参数 keep_rcv_buf。
|
||
* @param recv_pkg_size -接收应答包的buff的初始大小。函数返回0时,返回报文实际长度。
|
||
* @param timeout -超时时间, 单位ms
|
||
* @param check_func -检测报文是否成功到达函数
|
||
* @param msg_ctx -解析报文的上下文变量。
|
||
* @param keep_rcv_buf -true,框架将最后的rcv_buf赋值给传出参数,业务负责释放该buf。否则框架在调用结束前释放该buf。【注意】
|
||
* 业务需要自己在msg_ctx中保留相关信息。【框架通过malloc申请内存】
|
||
* @return 0 成功, -1 打开socket失败, -2 发送请求失败, -3 接收应答失败,
|
||
* -4 连接失败, -5 检测报文失败, -6 接收空间不够, -7 后端主动关闭连接, -10 参数无效
|
||
*/
|
||
int mt_tcpsendrcv(struct sockaddr_in* dst, void* pkg, int len, void*& rcv_buf, int& recv_pkg_size,
|
||
int timeout, MtFuncTcpMsgChecker check_func, void* msg_ctx=NULL, bool keep_rcv_buf=false);
|
||
|
||
|
||
/******************************************************************************/
|
||
/* 微线程用户接口定义: 微线程Task多路并发模型接口定义 */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief 微线程子任务对象定义
|
||
*/
|
||
class IMtTask
|
||
{
|
||
public:
|
||
|
||
/**
|
||
* @brief 微线程任务类的处理流程入口函数
|
||
* @return 0 -成功, < 0 失败
|
||
*/
|
||
virtual int Process() { return -1; };
|
||
|
||
/**
|
||
* @brief 设置task执行结果
|
||
* @info 即Process返回值
|
||
*/
|
||
void SetResult(int rc)
|
||
{
|
||
_result = rc;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取task执行结果
|
||
* @info 即Process返回值
|
||
*/
|
||
int GetResult(void)
|
||
{
|
||
return _result;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置task类型
|
||
*/
|
||
void SetTaskType(int type)
|
||
{
|
||
_type = type;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取task类型
|
||
* @info 如果业务有多种task,可以使用该字段区分不同的task类型
|
||
* @return 获取task类型
|
||
*/
|
||
int GetTaskType(void)
|
||
{
|
||
return _type;
|
||
}
|
||
|
||
/**
|
||
* @brief 微线程任务基类构造与析构
|
||
*/
|
||
IMtTask() {};
|
||
virtual ~IMtTask() {};
|
||
|
||
protected:
|
||
|
||
int _type; // task类型,多种类型task,业务可以自定义类型,方便从基类转换
|
||
int _result; // task执行结果,即Process返回值
|
||
};
|
||
|
||
typedef vector<IMtTask*> IMtTaskList;
|
||
|
||
/**
|
||
* @brief 多路IO并发, Task-fork-wait模式接口
|
||
* @param req_list -task list 封装独立api的task列表
|
||
* @return 0 成功, -1 创建子线程失败
|
||
*/
|
||
int mt_exec_all_task(IMtTaskList& req_list);
|
||
|
||
|
||
/******************************************************************************/
|
||
/* 微线程用户接口定义: 微线程封装系统接口 */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief 微线程主动sleep接口, 单位ms
|
||
* @info 业务需要主动让出CPU时使用
|
||
*/
|
||
void mt_sleep(int ms);
|
||
|
||
/**
|
||
* @brief 微线程获取系统时间,单位ms
|
||
*/
|
||
unsigned long long mt_time_ms(void);
|
||
|
||
/******************************************************************************/
|
||
/* 微线程用户接口定义: 微线程用户私有数据接口 */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief 设置当前IMtMsg的私有变量
|
||
* @info 只保存指针,内存需要业务分配
|
||
*/
|
||
void mt_set_msg_private(void *data);
|
||
|
||
/**
|
||
* @brief 获取当前IMtMsg的私有变量
|
||
* @return 私有变量指针
|
||
*/
|
||
void* mt_get_msg_private();
|
||
|
||
|
||
/******************************************************************************/
|
||
/* 微线程用户接口定义: 微线程封装系统接口(不推荐使用) */
|
||
/******************************************************************************/
|
||
|
||
/**
|
||
* @brief 微线程框架初始化
|
||
* @info 业务不使用spp,裸用微线程,需要调用该函数初始化框架;
|
||
* 使用spp,直接调用SyncFrame的框架初始化函数即可
|
||
* @return false:初始化失败 true:初始化成功
|
||
*/
|
||
bool mt_init_frame(int argc=0, char * const argv[]=NULL);
|
||
|
||
/**
|
||
* @brief 设置微线程独立栈空间大小
|
||
* @info 非必须设置,默认大小为128K
|
||
*/
|
||
void mt_set_stack_size(unsigned int bytes);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 recvfrom
|
||
* @param fd 系统socket信息
|
||
* @param buf 接收消息缓冲区指针
|
||
* @param len 接收消息缓冲区长度
|
||
* @param from 来源地址的指针
|
||
* @param fromlen 来源地址的结构长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功接收长度, <0 失败
|
||
*/
|
||
int mt_recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 sendto
|
||
* @param fd 系统socket信息
|
||
* @param msg 待发送的消息指针
|
||
* @param len 待发送的消息长度
|
||
* @param to 目的地址的指针
|
||
* @param tolen 目的地址的结构长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功发送长度, <0 失败
|
||
*/
|
||
int mt_sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
|
||
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 connect
|
||
* @param fd 系统socket信息
|
||
* @param addr 指定server的目的地址
|
||
* @param addrlen 地址的长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功发送长度, <0 失败
|
||
*/
|
||
int mt_connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 accept
|
||
* @param fd 监听套接字
|
||
* @param addr 客户端地址
|
||
* @param addrlen 地址的长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >=0 accept的socket描述符, <0 失败
|
||
*/
|
||
int mt_accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 read
|
||
* @param fd 系统socket信息
|
||
* @param buf 接收消息缓冲区指针
|
||
* @param nbyte 接收消息缓冲区长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功接收长度, <0 失败
|
||
*/
|
||
ssize_t mt_read(int fd, void *buf, size_t nbyte, int timeout);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 write
|
||
* @param fd 系统socket信息
|
||
* @param buf 待发送的消息指针
|
||
* @param nbyte 待发送的消息长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功发送长度, <0 失败
|
||
*/
|
||
ssize_t mt_write(int fd, const void *buf, size_t nbyte, int timeout);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 recv
|
||
* @param fd 系统socket信息
|
||
* @param buf 接收消息缓冲区指针
|
||
* @param len 接收消息缓冲区长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功接收长度, <0 失败
|
||
*/
|
||
ssize_t mt_recv(int fd, void *buf, int len, int flags, int timeout);
|
||
|
||
/**
|
||
* @brief 微线程包裹的系统IO函数 send
|
||
* @param fd 系统socket信息
|
||
* @param buf 待发送的消息指针
|
||
* @param nbyte 待发送的消息长度
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 成功发送长度, <0 失败
|
||
*/
|
||
ssize_t mt_send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
|
||
|
||
|
||
/**
|
||
* @brief 微线程等待epoll事件的包裹函数
|
||
* @param fd 系统socket信息
|
||
* @param events 等待的事件 IN/OUT
|
||
* @param timeout 最长等待时间, 毫秒
|
||
* @return >0 到达的事件, <0 失败
|
||
*/
|
||
int mt_wait_events(int fd, int events, int timeout);
|
||
|
||
|
||
void* mt_start_thread(void* entry, void* args);
|
||
|
||
|
||
}
|
||
|
||
#endif
|
||
|
||
|