/* * MIT License * * Copyright (c) 2019 xiongziliang <771730766@qq.com> * * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit). * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include "mk_mediakit.h" #ifdef _WIN32 #include "windows.h" #else #include "unistd.h" #endif #define LOG_LEV 4 //修改此宏,可以选择协议类型 #define TCP_TYPE mk_type_ws static int flag = 1; static void s_on_exit(int sig){ flag = 0; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct { mk_tcp_session _session; //下面你可以夹杂你的私货数据 char your_some_useful_data[1024]; } tcp_session_user_data; /** * 当tcp客户端连接服务器时触发 * @param session 会话处理对象 */ void API_CALL on_mk_tcp_session_create(uint16_t server_port,mk_tcp_session session){ log_printf(LOG_LEV,"%s %d",mk_tcp_session_peer_ip(session),(int)mk_tcp_session_peer_port(session)); tcp_session_user_data *user_data = malloc(sizeof(tcp_session_user_data)); user_data->_session = session; mk_tcp_session_set_user_data(session,user_data); } /** * 收到tcp客户端发过来的数据 * @param session 会话处理对象 * @param data 数据指针 * @param len 数据长度 */ void API_CALL on_mk_tcp_session_data(uint16_t server_port,mk_tcp_session session,const char *data,int len){ log_printf(LOG_LEV,"from %s %d, data[%d]: %s",mk_tcp_session_peer_ip(session),(int)mk_tcp_session_peer_port(session), len,data); mk_tcp_session_send(session,"echo:",0); mk_tcp_session_send(session,data,len); } /** * 每隔2秒的定时器,用于管理超时等任务 * @param session 会话处理对象 */ void API_CALL on_mk_tcp_session_manager(uint16_t server_port,mk_tcp_session session){ log_printf(LOG_LEV,"%s %d",mk_tcp_session_peer_ip(session),(int)mk_tcp_session_peer_port(session)); } /** * 一般由于客户端断开tcp触发 * 本事件中可以调用mk_tcp_session_send_safe函数 * @param session 会话处理对象 * @param code 错误代码 * @param msg 错误提示 */ void API_CALL on_mk_tcp_session_disconnect(uint16_t server_port,mk_tcp_session session,int code,const char *msg){ log_printf(LOG_LEV,"%s %d: %d %s",mk_tcp_session_peer_ip(session),(int)mk_tcp_session_peer_port(session),code,msg); tcp_session_user_data *user_data = (tcp_session_user_data *)mk_tcp_session_get_user_data(session); free(user_data); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct { mk_tcp_client client; //下面你可以夹杂你的私货数据 char your_some_useful_data[1024]; int count; } tcp_client_user_data; /** * tcp客户端连接服务器成功或失败回调 * @param client tcp客户端 * @param code 0为连接成功,否则为失败原因 * @param msg 连接失败错误提示 */ void API_CALL on_mk_tcp_client_connect(mk_tcp_client client,int code,const char *msg){ log_printf(LOG_LEV,"connect result:%d %s",code,msg); if(code == 0){ //连接上后我们发送一个hello world测试数据 mk_tcp_client_send(client,"hello world",0); }else{ tcp_client_user_data *user_data = mk_tcp_client_get_user_data(client); mk_tcp_client_release(client); free(user_data); } } /** * tcp客户端与tcp服务器之间断开回调 * 一般是eof事件导致 * @param client tcp客户端 * @param code 错误代码 * @param msg 错误提示 */ void API_CALL on_mk_tcp_client_disconnect(mk_tcp_client client,int code,const char *msg){ log_printf(LOG_LEV,"disconnect:%d %s",code,msg); //服务器主动断开了,我们销毁对象 tcp_client_user_data *user_data = mk_tcp_client_get_user_data(client); mk_tcp_client_release(client); free(user_data); } /** * 收到tcp服务器发来的数据 * @param client tcp客户端 * @param data 数据指针 * @param len 数据长度 */ void API_CALL on_mk_tcp_client_data(mk_tcp_client client,const char *data,int len){ log_printf(LOG_LEV,"data[%d]:%s",len,data); } /** * 每隔2秒的定时器,用于管理超时等任务 * @param client tcp客户端 */ void API_CALL on_mk_tcp_client_manager(mk_tcp_client client){ tcp_client_user_data *user_data = mk_tcp_client_get_user_data(client); char buf[1024]; sprintf(buf,"on_mk_tcp_client_manager:%d",user_data->count); mk_tcp_client_send(client,buf,0); if(++user_data->count == 5){ //发送5遍后主动释放对象 mk_tcp_client_release(client); free(user_data); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// void test_server(){ mk_tcp_session_events events_server = { .on_mk_tcp_session_create = on_mk_tcp_session_create, .on_mk_tcp_session_data = on_mk_tcp_session_data, .on_mk_tcp_session_manager = on_mk_tcp_session_manager, .on_mk_tcp_session_disconnect = on_mk_tcp_session_disconnect }; mk_tcp_server_events_listen(&events_server); mk_tcp_server_start(80, TCP_TYPE); } void test_client(){ mk_tcp_client_events events_clent = { .on_mk_tcp_client_connect = on_mk_tcp_client_connect, .on_mk_tcp_client_data = on_mk_tcp_client_data, .on_mk_tcp_client_disconnect = on_mk_tcp_client_disconnect, .on_mk_tcp_client_manager = on_mk_tcp_client_manager, }; mk_tcp_client client = mk_tcp_client_create(&events_clent, TCP_TYPE); tcp_client_user_data *user_data = (tcp_client_user_data *)malloc(sizeof(tcp_client_user_data)); user_data->client = client; user_data->count = 0; mk_tcp_client_set_user_data(client,user_data); mk_tcp_client_connect(client, "121.40.165.18", 8800, 3); //你可以连接127.0.0.1 80测试 // mk_tcp_client_connect(client, "127.0.0.1", 80, 3); } int main(int argc, char *argv[]) { char *ini_path = mk_util_get_exe_dir("c_api.ini"); char *ssl_path = mk_util_get_exe_dir("ssl.p12"); mk_config config = { .ini = ini_path, .ini_is_path = 1, .log_level = 0, .ssl = ssl_path, .ssl_is_path = 1, .ssl_pwd = NULL, .thread_num = 0 }; mk_env_init(&config); free(ini_path); free(ssl_path); test_server(); test_client(); signal(SIGINT, s_on_exit );// 设置退出信号 while (flag) { #ifdef _WIN32 Sleep(1000); #else sleep(1); #endif } mk_stop_all_server(); return 0; }