1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Use of this source code is governed by MIT license that can be found in the 7*4882a593Smuzhiyun * LICENSE file in the root of the source tree. All contributing project authors 8*4882a593Smuzhiyun * may be found in the AUTHORS file in the root of the source tree. 9*4882a593Smuzhiyun */ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifndef MK_TCP_H 12*4882a593Smuzhiyun #define MK_TCP_H 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include "mk_common.h" 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #ifdef __cplusplus 17*4882a593Smuzhiyun extern "C" { 18*4882a593Smuzhiyun #endif 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun ///////////////////////////////////////////Buffer::Ptr///////////////////////////////////////////// 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun typedef void *mk_buffer; 23*4882a593Smuzhiyun typedef void(API_CALL *on_mk_buffer_free)(void *user_data, void *data); 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun /** 26*4882a593Smuzhiyun * 创建buffer对象 27*4882a593Smuzhiyun * @param data 数据指针 28*4882a593Smuzhiyun * @param len 数据长度 29*4882a593Smuzhiyun * @param cb 数据指针free回调函数,该参数置空时,内部会拷贝数据 30*4882a593Smuzhiyun * @param user_data 数据指针free回调函数on_mk_buffer_free第一个参数 31*4882a593Smuzhiyun * @return buffer对象 32*4882a593Smuzhiyun */ 33*4882a593Smuzhiyun API_EXPORT mk_buffer API_CALL mk_buffer_from_char(const char *data, size_t len, on_mk_buffer_free cb, void *user_data); 34*4882a593Smuzhiyun API_EXPORT mk_buffer API_CALL mk_buffer_ref(mk_buffer buffer); 35*4882a593Smuzhiyun API_EXPORT void API_CALL mk_buffer_unref(mk_buffer buffer); 36*4882a593Smuzhiyun API_EXPORT const char* API_CALL mk_buffer_get_data(mk_buffer buffer); 37*4882a593Smuzhiyun API_EXPORT size_t API_CALL mk_buffer_get_size(mk_buffer buffer); 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun ///////////////////////////////////////////SockInfo///////////////////////////////////////////// 40*4882a593Smuzhiyun //SockInfo对象的C映射 41*4882a593Smuzhiyun typedef void* mk_sock_info; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun //SockInfo::get_peer_ip() 44*4882a593Smuzhiyun API_EXPORT const char* API_CALL mk_sock_info_peer_ip(const mk_sock_info ctx, char *buf); 45*4882a593Smuzhiyun //SockInfo::get_local_ip() 46*4882a593Smuzhiyun API_EXPORT const char* API_CALL mk_sock_info_local_ip(const mk_sock_info ctx, char *buf); 47*4882a593Smuzhiyun //SockInfo::get_peer_port() 48*4882a593Smuzhiyun API_EXPORT uint16_t API_CALL mk_sock_info_peer_port(const mk_sock_info ctx); 49*4882a593Smuzhiyun //SockInfo::get_local_port() 50*4882a593Smuzhiyun API_EXPORT uint16_t API_CALL mk_sock_info_local_port(const mk_sock_info ctx); 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun #ifndef SOCK_INFO_API_RENAME 53*4882a593Smuzhiyun #define SOCK_INFO_API_RENAME 54*4882a593Smuzhiyun //mk_tcp_session对象转换成mk_sock_info对象后再获取网络相关信息 55*4882a593Smuzhiyun #define mk_tcp_session_peer_ip(x,buf) mk_sock_info_peer_ip(mk_tcp_session_get_sock_info(x),buf) 56*4882a593Smuzhiyun #define mk_tcp_session_local_ip(x,buf) mk_sock_info_local_ip(mk_tcp_session_get_sock_info(x),buf) 57*4882a593Smuzhiyun #define mk_tcp_session_peer_port(x) mk_sock_info_peer_port(mk_tcp_session_get_sock_info(x)) 58*4882a593Smuzhiyun #define mk_tcp_session_local_port(x) mk_sock_info_local_port(mk_tcp_session_get_sock_info(x)) 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun //mk_tcp_client对象转换成mk_sock_info对象后再获取网络相关信息 61*4882a593Smuzhiyun #define mk_tcp_client_peer_ip(x,buf) mk_sock_info_peer_ip(mk_tcp_client_get_sock_info(x),buf) 62*4882a593Smuzhiyun #define mk_tcp_client_local_ip(x,buf) mk_sock_info_local_ip(mk_tcp_client_get_sock_info(x),buf) 63*4882a593Smuzhiyun #define mk_tcp_client_peer_port(x) mk_sock_info_peer_port(mk_tcp_client_get_sock_info(x)) 64*4882a593Smuzhiyun #define mk_tcp_client_local_port(x) mk_sock_info_local_port(mk_tcp_client_get_sock_info(x)) 65*4882a593Smuzhiyun #endif 66*4882a593Smuzhiyun ///////////////////////////////////////////TcpSession///////////////////////////////////////////// 67*4882a593Smuzhiyun //TcpSession对象的C映射 68*4882a593Smuzhiyun typedef void* mk_tcp_session; 69*4882a593Smuzhiyun typedef void* mk_tcp_session_ref; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun //获取基类指针以便获取其网络相关信息 72*4882a593Smuzhiyun API_EXPORT mk_sock_info API_CALL mk_tcp_session_get_sock_info(const mk_tcp_session ctx); 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun //TcpSession::safeShutdown() 75*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_session_shutdown(const mk_tcp_session ctx,int err,const char *err_msg); 76*4882a593Smuzhiyun //TcpSession::send() 77*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_session_send(const mk_tcp_session ctx, const char *data, size_t len); 78*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_session_send_buffer(const mk_tcp_session ctx, mk_buffer buffer); 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun //切换到该对象所在线程后再TcpSession::send() 81*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_session_send_safe(const mk_tcp_session ctx, const char *data, size_t len); 82*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_session_send_buffer_safe(const mk_tcp_session ctx, mk_buffer buffer); 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun //创建mk_tcp_session的弱引用 85*4882a593Smuzhiyun API_EXPORT mk_tcp_session_ref API_CALL mk_tcp_session_ref_from(const mk_tcp_session ctx); 86*4882a593Smuzhiyun //删除mk_tcp_session的弱引用 87*4882a593Smuzhiyun API_EXPORT void mk_tcp_session_ref_release(const mk_tcp_session_ref ref); 88*4882a593Smuzhiyun //根据弱引用获取mk_tcp_session,如果mk_tcp_session已经销毁,那么返回NULL 89*4882a593Smuzhiyun API_EXPORT mk_tcp_session mk_tcp_session_from_ref(const mk_tcp_session_ref ref); 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun ///////////////////////////////////////////自定义tcp服务///////////////////////////////////////////// 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun typedef struct { 94*4882a593Smuzhiyun /** 95*4882a593Smuzhiyun * 收到mk_tcp_session创建对象 96*4882a593Smuzhiyun * @param server_port 服务器端口号 97*4882a593Smuzhiyun * @param session 会话处理对象 98*4882a593Smuzhiyun */ 99*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_session_create)(uint16_t server_port,mk_tcp_session session); 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /** 102*4882a593Smuzhiyun * 收到客户端发过来的数据 103*4882a593Smuzhiyun * @param server_port 服务器端口号 104*4882a593Smuzhiyun * @param session 会话处理对象 105*4882a593Smuzhiyun * @param buffer 数据 106*4882a593Smuzhiyun */ 107*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_session_data)(uint16_t server_port,mk_tcp_session session, mk_buffer buffer); 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun /** 110*4882a593Smuzhiyun * 每隔2秒的定时器,用于管理超时等任务 111*4882a593Smuzhiyun * @param server_port 服务器端口号 112*4882a593Smuzhiyun * @param session 会话处理对象 113*4882a593Smuzhiyun */ 114*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_session_manager)(uint16_t server_port,mk_tcp_session session); 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun /** 117*4882a593Smuzhiyun * 一般由于客户端断开tcp触发 118*4882a593Smuzhiyun * @param server_port 服务器端口号 119*4882a593Smuzhiyun * @param session 会话处理对象 120*4882a593Smuzhiyun * @param code 错误代码 121*4882a593Smuzhiyun * @param msg 错误提示 122*4882a593Smuzhiyun */ 123*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_session_disconnect)(uint16_t server_port,mk_tcp_session session,int code,const char *msg); 124*4882a593Smuzhiyun } mk_tcp_session_events; 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun typedef enum { 128*4882a593Smuzhiyun //普通的tcp 129*4882a593Smuzhiyun mk_type_tcp = 0, 130*4882a593Smuzhiyun //ssl类型的tcp 131*4882a593Smuzhiyun mk_type_ssl = 1, 132*4882a593Smuzhiyun //基于websocket的连接 133*4882a593Smuzhiyun mk_type_ws = 2, 134*4882a593Smuzhiyun //基于ssl websocket的连接 135*4882a593Smuzhiyun mk_type_wss = 3 136*4882a593Smuzhiyun }mk_tcp_type; 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun /** 139*4882a593Smuzhiyun * tcp会话对象附着用户数据 140*4882a593Smuzhiyun * 该函数只对mk_tcp_server_server_start启动的服务类型有效 141*4882a593Smuzhiyun * @param session 会话对象 142*4882a593Smuzhiyun * @param user_data 用户数据指针 143*4882a593Smuzhiyun */ 144*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_session_set_user_data(mk_tcp_session session,void *user_data); 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun /** 147*4882a593Smuzhiyun * 获取tcp会话对象上附着的用户数据 148*4882a593Smuzhiyun * 该函数只对mk_tcp_server_server_start启动的服务类型有效 149*4882a593Smuzhiyun * @param session tcp会话对象 150*4882a593Smuzhiyun * @return 用户数据指针 151*4882a593Smuzhiyun */ 152*4882a593Smuzhiyun API_EXPORT void* API_CALL mk_tcp_session_get_user_data(mk_tcp_session session); 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun /** 155*4882a593Smuzhiyun * 开启tcp服务器 156*4882a593Smuzhiyun * @param port 监听端口号,0则为随机 157*4882a593Smuzhiyun * @param type 服务器类型 158*4882a593Smuzhiyun */ 159*4882a593Smuzhiyun API_EXPORT uint16_t API_CALL mk_tcp_server_start(uint16_t port, mk_tcp_type type); 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun /** 162*4882a593Smuzhiyun * 监听tcp服务器事件 163*4882a593Smuzhiyun */ 164*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_server_events_listen(const mk_tcp_session_events *events); 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun ///////////////////////////////////////////自定义tcp客户端///////////////////////////////////////////// 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun typedef void* mk_tcp_client; 170*4882a593Smuzhiyun //获取基类指针以便获取其网络相关信息 171*4882a593Smuzhiyun API_EXPORT mk_sock_info API_CALL mk_tcp_client_get_sock_info(const mk_tcp_client ctx); 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun typedef struct { 174*4882a593Smuzhiyun /** 175*4882a593Smuzhiyun * tcp客户端连接服务器成功或失败回调 176*4882a593Smuzhiyun * @param client tcp客户端 177*4882a593Smuzhiyun * @param code 0为连接成功,否则为失败原因 178*4882a593Smuzhiyun * @param msg 连接失败错误提示 179*4882a593Smuzhiyun */ 180*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_client_connect)(mk_tcp_client client,int code,const char *msg); 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun /** 183*4882a593Smuzhiyun * tcp客户端与tcp服务器之间断开回调 184*4882a593Smuzhiyun * 一般是eof事件导致 185*4882a593Smuzhiyun * @param client tcp客户端 186*4882a593Smuzhiyun * @param code 错误代码 187*4882a593Smuzhiyun * @param msg 错误提示 188*4882a593Smuzhiyun */ 189*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_client_disconnect)(mk_tcp_client client,int code,const char *msg); 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun /** 192*4882a593Smuzhiyun * 收到tcp服务器发来的数据 193*4882a593Smuzhiyun * @param client tcp客户端 194*4882a593Smuzhiyun * @param buffer 数据 195*4882a593Smuzhiyun */ 196*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_client_data)(mk_tcp_client client, mk_buffer buffer); 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun /** 199*4882a593Smuzhiyun * 每隔2秒的定时器,用于管理超时等任务 200*4882a593Smuzhiyun * @param client tcp客户端 201*4882a593Smuzhiyun */ 202*4882a593Smuzhiyun void (API_CALL *on_mk_tcp_client_manager)(mk_tcp_client client); 203*4882a593Smuzhiyun } mk_tcp_client_events; 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /** 206*4882a593Smuzhiyun * 创建tcp客户端 207*4882a593Smuzhiyun * @param events 回调函数结构体 208*4882a593Smuzhiyun * @param user_data 用户数据指针 209*4882a593Smuzhiyun * @param type 客户端类型 210*4882a593Smuzhiyun * @return 客户端对象 211*4882a593Smuzhiyun */ 212*4882a593Smuzhiyun API_EXPORT mk_tcp_client API_CALL mk_tcp_client_create(mk_tcp_client_events *events, mk_tcp_type type); 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun /** 215*4882a593Smuzhiyun * 释放tcp客户端 216*4882a593Smuzhiyun * @param ctx 客户端对象 217*4882a593Smuzhiyun */ 218*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_release(mk_tcp_client ctx); 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun /** 221*4882a593Smuzhiyun * 发起连接 222*4882a593Smuzhiyun * @param ctx 客户端对象 223*4882a593Smuzhiyun * @param host 服务器ip或域名 224*4882a593Smuzhiyun * @param port 服务器端口号 225*4882a593Smuzhiyun * @param time_out_sec 超时时间 226*4882a593Smuzhiyun */ 227*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_connect(mk_tcp_client ctx, const char *host, uint16_t port, float time_out_sec); 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun /** 230*4882a593Smuzhiyun * 非线程安全的发送数据 231*4882a593Smuzhiyun * 开发者如果能确保在本对象网络线程内,可以调用此此函数 232*4882a593Smuzhiyun * @param ctx 客户端对象 233*4882a593Smuzhiyun * @param data 数据指针 234*4882a593Smuzhiyun * @param len 数据长度,等于0时,内部通过strlen获取 235*4882a593Smuzhiyun */ 236*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_send(mk_tcp_client ctx, const char *data, int len); 237*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_send_buffer(mk_tcp_client ctx, mk_buffer buffer); 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun /** 240*4882a593Smuzhiyun * 切换到本对象的网络线程后再发送数据 241*4882a593Smuzhiyun * @param ctx 客户端对象 242*4882a593Smuzhiyun * @param data 数据指针 243*4882a593Smuzhiyun * @param len 数据长度,等于0时,内部通过strlen获取 244*4882a593Smuzhiyun */ 245*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_send_safe(mk_tcp_client ctx, const char *data, int len); 246*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_send_buffer_safe(mk_tcp_client ctx, mk_buffer buffer); 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun /** 249*4882a593Smuzhiyun * 客户端附着用户数据 250*4882a593Smuzhiyun * @param ctx 客户端对象 251*4882a593Smuzhiyun * @param user_data 用户数据指针 252*4882a593Smuzhiyun */ 253*4882a593Smuzhiyun API_EXPORT void API_CALL mk_tcp_client_set_user_data(mk_tcp_client ctx,void *user_data); 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /** 256*4882a593Smuzhiyun * 获取客户端对象上附着的用户数据 257*4882a593Smuzhiyun * @param ctx 客户端对象 258*4882a593Smuzhiyun * @return 用户数据指针 259*4882a593Smuzhiyun */ 260*4882a593Smuzhiyun API_EXPORT void* API_CALL mk_tcp_client_get_user_data(mk_tcp_client ctx); 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun #ifdef __cplusplus 263*4882a593Smuzhiyun } 264*4882a593Smuzhiyun #endif 265*4882a593Smuzhiyun #endif //MK_TCP_H 266