在以下代码中,有关socket接收的处理,加入接收完所有数据或接收数据出错,安全退出的功能:/*-----------------------------------------------------------------------------*/
/* Including Files */
/*-----------------------------------------------------------------------------*/
#include "ai3_usr_lib.h"
// platform dependent
#if defined(__LINUX)
#include <pthread.h> //for pthread API
#define MAIN(argc, argv) int main(int argc, char** argv)
#define GETCHAR() getchar()
#else
#include <FreeRTOS_POSIX.h>
#include <FreeRTOS_POSIX/pthread.h> //for pthread API
#include <kwrap/util.h> //for sleep API
#define sleep(x) vos_util_delay_ms(1000*(x))
#define msleep(x) vos_util_delay_ms(x)
#define usleep(x) vos_util_delay_us(x)
#include <kwrap/examsys.h> //for MAIN(), GETCHAR() API
#define MAIN(argc, argv) EXAMFUNC_ENTRY(ai3_sample_list, argc, argv)
#endif
#include <sys/socket.h> // socket头文件
#include <netinet/in.h> // 网络地址结构头文件
#include <arpa/inet.h> // 地址转换函数头文件
#include <unistd.h> // close函数头文件
#include <errno.h> // 错误代码头文件
#define SOCKET_PORT 8887 // 定义Socket端口号
#define MAX_CLIENTS 2 // 最大客户端连接数
#define IN_BUFF_SIZE 4096
#define VENDOR_AI_CFG 0x000f0000 //vendor ai config
#define OUTPUT 1 // 是否输出,debug用
UINT64 proc_num = 10;
UINT32 debug_input_info = 0;
UINT32 debug_dump_ut = 0;
UINT32 debug_dump_bw = 0;
UINT64 dump_time_print_freq = 300;
static HD_RESULT usr_alloc_input_mem(NET_PROC *p_net)
{
HD_RESULT ret = HD_OK;
UINT32 i;
VENDOR_AI3_BUF ai_buf = {0};
CHAR mem_name[STRING_LEN];
MEM_PARM mem_parm;
p_net->in_buf = (VENDOR_AI3_BUF *)malloc(sizeof(VENDOR_AI3_BUF) * p_net->net_info.in_buf_cnt);
for (i = 0; i < p_net->net_info.in_buf_cnt; i++) {
ret = vendor_ai3_net_get(p_net->proc_id, p_net->net_info.in_path_list[i], &ai_buf);
if (HD_OK != ret) {
printf("net_path(%u), proc_id(%u) get in buf fail, i(%u), in_path(0x%x)\n", p_net->net_id, p_net->proc_id, i, p_net->net_info.in_path_list[i]);
return ret;
}
if (debug_input_info){
printf("input %d, time = %d\r\n", i, ai_buf.time);
printf("input %d, batch_num = %d\r\n", i, ai_buf.batch_num);
printf("input %d, channel = %d\r\n", i, ai_buf.channel);
printf("input %d, height = %d\r\n", i, ai_buf.height);
printf("input %d, width = %d\r\n", i, ai_buf.width);
printf("input %d, fmt = 0x%08X\r\n", i, ai_buf.fmt);
printf("input %d, line_ofs = %lld\r\n", i, ai_buf.line_ofs);
printf("input %d, scale_ratio = %f\r\n", i, ai_buf.scale_ratio);
printf("input %d, zero_point = %d\r\n", i, ai_buf.zero_point);
printf("input %d, name = %s\r\n", i, ai_buf.name);
printf("input %d, sign = %d\r\n", i, ai_buf.sign);
// printf("input %d, MAKEFOURCC('A', 'B', 'U', 'F') = %d\r\n", i, MAKEFOURCC('A', 'B', 'U', 'F'));
}
UINT32 temp_fmt = ((ai_buf.fmt) & (HD_VIDEO_PXLFMT_CLASS_MASK | HD_VIDEO_PXLFMT_PLANE_MASK | HD_VIDEO_PXLFMT_BPP_MASK)); //HD_VIDEO_PXLFMT_TYPE(pxlfmt)
if (HD_VIDEO_PXLFMT_YUV420 == ai_buf.fmt) {
ai_buf.size = ai_buf.batch_num * 3 * ai_buf.height * ai_buf.line_ofs / 2;
} else if (HD_VIDEO_PXLFMT_RGB888_PLANAR == ai_buf.fmt || HD_VIDEO_PXLFMT_BGR888_PLANAR == ai_buf.fmt) {
ai_buf.size = ai_buf.batch_num * 3 * ai_buf.height * ai_buf.line_ofs;
} else if (HD_VIDEO_PXLFMT_Y8 == ai_buf.fmt || HD_VIDEO_PXLFMT_UV == ai_buf.fmt) {
ai_buf.size = ai_buf.batch_num * 1 * ai_buf.height * ai_buf.line_ofs;
} else if (HD_VIDEO_PXLFMT_AI_UINT8 == temp_fmt || HD_VIDEO_PXLFMT_AI_SINT8 == temp_fmt) {
ai_buf.size = ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.line_ofs;
} else if (HD_VIDEO_PXLFMT_AI_UINT16 == temp_fmt || HD_VIDEO_PXLFMT_AI_SINT16 == temp_fmt) {
ai_buf.size = ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.line_ofs;
} else if (HD_VIDEO_PXLFMT_AI_UINT32 == temp_fmt || HD_VIDEO_PXLFMT_AI_SINT32 == temp_fmt) {
ai_buf.size = ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.line_ofs;
} else if (HD_VIDEO_PXLFMT_AI_FLOAT32 == temp_fmt) {
ai_buf.size = ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.line_ofs;
}
snprintf(mem_name, STRING_LEN, "ai input %u %u", p_net->net_id, i);
ret = mem_alloc(&mem_parm, mem_name, ai_buf.size, p_net->ddr);
if (HD_OK != ret) {
printf("net_path(%u) mem_alloc input i(%u) fail !!\n", p_net->net_id, i);
return ret;
}
ai_buf.va = mem_parm.va;
ai_buf.pa = mem_parm.pa;
ai_buf.size = mem_parm.size;
ai_buf.sign = MAKEFOURCC('A', 'B', 'U', 'F');
if (debug_input_info){
printf("input %d, pa = %#lx\r\n", i, ai_buf.pa);
printf("input %d, va = %#lx\r\n", i, ai_buf.va);
printf("input %d, size = %d\r\n", i, ai_buf.size);
}
p_net->in_buf[i] = ai_buf;
}
return ret;
}
static HD_RESULT usr_free_input_mem(NET_PROC *p_net)
{
HD_RESULT ret = HD_OK;
UINT32 i;
MEM_PARM mem_parm;
for (i = 0; i < p_net->net_info.in_buf_cnt; i++) {
if(p_net->in_buf && p_net->in_buf[i].va) {
mem_parm.va = p_net->in_buf[i].va;
mem_parm.pa = p_net->in_buf[i].pa;
mem_parm.size = p_net->in_buf[i].size;
mem_free(&mem_parm);
}
}
if (p_net->in_buf) {
free(p_net->in_buf);
}
return ret;
}
static HD_RESULT usr_alloc_output_mem(NET_PROC *p_net)
{
HD_RESULT ret = HD_OK;
UINT32 i;
VENDOR_AI3_BUF ai_buf = {0};
CHAR mem_name[STRING_LEN];
MEM_PARM mem_parm;
p_net->out_mem = (MEM_PARM *)malloc(sizeof(MEM_PARM) * p_net->net_info.out_buf_cnt);
p_net->out_mem_float = (MEM_PARM *)malloc(sizeof(MEM_PARM) * p_net->net_info.out_buf_cnt);
for (i = 0; i < p_net->net_info.out_buf_cnt; i++) {
ret = vendor_ai3_net_get(p_net->proc_id, p_net->net_info.out_path_list[i], &ai_buf);
if (HD_OK != ret) {
printf("net_path(%u), proc_id(%u) get in buf fail, i(%u), in_path(0x%x)\n", p_net->net_id, p_net->proc_id, i, p_net->net_info.out_path_list[i]);
return ret;
}
if (debug_input_info){
printf("output %d, time = %d\r\n", i, ai_buf.time);
printf("output %d, batch_num = %d\r\n", i, ai_buf.batch_num);
printf("output %d, channel = %d\r\n", i, ai_buf.channel);
printf("output %d, height = %d\r\n", i, ai_buf.height);
printf("output %d, width = %d\r\n", i, ai_buf.width);
printf("output %d, fmt = 0x%08X\r\n", i, ai_buf.fmt);
printf("output %d, line_ofs = %lld\r\n", i, ai_buf.line_ofs);
printf("output %d, pa = %#lx\r\n", i, ai_buf.pa);
printf("output %d, va = %#lx\r\n", i, ai_buf.va);
printf("output %d, size = %d\r\n", i, ai_buf.size);
printf("output %d, scale_ratio = %f\r\n", i, ai_buf.scale_ratio);
printf("output %d, zero_point = %d\r\n", i, ai_buf.zero_point);
printf("output %d, name = %s\r\n", i, ai_buf.name);
printf("output %d, sign = %d\r\n", i, ai_buf.sign);
// printf("input %d, MAKEFOURCC('A', 'B', 'U', 'F') = %d\r\n", i, MAKEFOURCC('A', 'B', 'U', 'F'));
}
snprintf(mem_name, STRING_LEN, "ai output %u %u", p_net->net_id, i);
ret = mem_alloc(&mem_parm, mem_name, ai_buf.size, p_net->ddr);
if (HD_OK != ret) {
printf("net_path(%u) mem_alloc output i(%u) fail !!\n", p_net->net_id, i);
return ret;
}
p_net->out_mem[i] = mem_parm;
#if OUTPUT==1
snprintf(mem_name, STRING_LEN, "ai output float %u %u", p_net->net_id, i);
INT32 size = ai_buf.time * ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.width;
ret = mem_alloc(&mem_parm, mem_name, size*sizeof(FLOAT), p_net->ddr);
if (HD_OK != ret) {
printf("net_path(%u) mem_alloc output float i(%u) fail !!\n", p_net->net_id, i);
return ret;
}
p_net->out_mem_float[i] = mem_parm;
#endif
}
return ret;
}
static HD_RESULT usr_free_output_mem(NET_PROC *p_net)
{
HD_RESULT ret = HD_OK;
UINT32 i;
for (i = 0; i < p_net->net_info.out_buf_cnt; i++) {
if(p_net->out_mem && p_net->out_mem[i].va) {
mem_free(&p_net->out_mem[i]);
}
}
if (p_net->out_mem) {
free(p_net->out_mem);
}
#if OUTPUT==1
for (i = 0; i < p_net->net_info.out_buf_cnt; i++) {
if(p_net->out_mem_float && p_net->out_mem_float[i].va) {
mem_free(&p_net->out_mem_float[i]);
}
}
if (p_net->out_mem_float) {
free(p_net->out_mem_float);
}
#endif
return ret;
}
/**
* @brief 通过Socket接收输入数据
* @param p_net 网络处理结构体指针
* @param sockfd Socket文件描述符
* @return HD_RESULT 操作结果
*/
static HD_RESULT receive_data_via_socket(NET_PROC *p_net, int sockfd) {
HD_RESULT ret = HD_OK;
UINT32 i;
for (i = 0; i < p_net->net_info.in_buf_cnt; i++) {
// 接收输入数据长度
UINT32 data_size = p_net -> in_buf[i].size; // 预期输入数据大小
size_t total_recevied = 0;
size_t remaining = data_size; // 剩余需要接收的
char *data_buffer = (char *)p_net->in_buf[i].va;
while (remaining > 0)
{
ssize_t bytes_received = recv(sockfd, data_buffer + total_recevied, remaining, 0);
if (bytes_received <= 0){
if (bytes_received == 0) {
printf("Client closed connection during data transfer\n");
} else {
perror("recv error during data transfer \n");
}
return HD_ERR_USER;
}
total_recevied += bytes_received;
remaining -= bytes_received;
}
printf("\n Received input %d data via socket, size: %u bytes\n", i, data_size);
}
return ret;
}
#if OUTPUT==1
/**
* @brief 通过Socket发送输出结果
* @param p_net 网络处理结构体指针
* @param sockfd Socket文件描述符
* @return HD_RESULT 操作结果
*/
static HD_RESULT send_data_via_socket(NET_PROC *p_net, int sockfd, UINT32 input_cnt, char* out_print) {
HD_RESULT ret = HD_OK;
UINT32 outlay_num = p_net->net_info.out_buf_cnt;
LONG total_size = 0;
VENDOR_AI3_BUF ai_buf = {0};
// FLOAT **outlayer_float = (FLOAT **)malloc(outlay_num * sizeof(FLOAT));
// if (outlayer_float == NULL)
// {
// printf("outlayer_float malloc size fail \n");
// return HD_ERR_FAIL;
// }
if (out_print == NULL)
{
printf("out_print malloc size fail \n");
return HD_ERR_FAIL;
}
total_size += sprintf(out_print + total_size, "input index %u\n", input_cnt);
/* 格式化输出结果 */
for (UINT32 i=0; i < outlay_num; i++)
{
ret = vendor_ai3_net_get(p_net->proc_id, p_net->net_info.out_path_list[i], &ai_buf);
if (HD_OK != ret) {
printf("net_path(%u), proc_id(%u) get out buf fail, i(%d), out_path(0x%x)\n", p_net->net_id, p_net->proc_id, i, p_net->net_info.out_path_list[i]);
return ret;
}
UINT32 out_size = ai_buf.time * ai_buf.batch_num * ai_buf.channel * ai_buf.height * ai_buf.width;
printf("#######output_size:%u\n", out_size);
FLOAT *curr_layer_float_ptr =(FLOAT *)p_net->out_mem_float[i].va;
for (UINT32 k = 0; k < out_size-1; k++)
{
total_size += sprintf(out_print + total_size, "%f ", *(curr_layer_float_ptr+k));
}
total_size += sprintf(out_print + total_size, "%f\n", *(curr_layer_float_ptr+(out_size-1)));
}
write(sockfd, out_print, total_size);
// 释放内存
// for (UINT32 i = 0; i < outlay_num; i++)
// {
// free(outlayer_float[i]);
// outlayer_float[i] = NULL;
// }
// free(outlayer_float);
// outlayer_float = NULL;
return ret;
}
#endif
/**
* @brief 设置Socket服务器
* @return int 监听Socket的文件描述符
*/
static int setup_socket_server(void) {
int server_fd;
struct sockaddr_in address;
int opt = 1;
// 创建Socket文件描述符
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置Socket选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 绑定地址和端口
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(SOCKET_PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 开始监听
if (listen(server_fd, MAX_CLIENTS) < 0) {
perror("listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Socket server listening on port %d\n", SOCKET_PORT);
return server_fd;
}
HD_RESULT run_ai_inference(CHAR *model_path,NET_DBG_DUMP_MODE debug_mode, int sockfd)
{
HD_RESULT ret = HD_OK;
NET_PROC net = {0};
// FILE *fd_test_list = NULL;
// CHAR test_list_path[STRING_LEN];
struct timeval tstart, tend;
static UINT64 cur_time = 0;
static UINT64 all_time = 0;
static UINT64 mean_time = 0;
UINT32 input_cnt = 0; // 记录输入测试数据的数量
UINT32 dump_mean_time = 16; // 每dump_mean_time次输出一次mean time信息
net.model_filename = model_path;
net.net_id = 0;
net.ddr = DDR_ID0;
net.job_priority = VENDOR_AI_JOB_PRI(0);
net.core_mask = VENDOR_AI_CORE_MASK_DEFAULT;
ret = network_init();
if (ret != HD_OK) {
printf("network_init fail=%d\n", ret);
goto exit;
}
ret = network_open(&net, debug_mode);
if (ret != HD_OK) {
printf("network_open fail=%d\n", ret);
goto exit;
}
ret = network_start(&net);
if (ret != HD_OK) {
printf("network_start fail=%d\n", ret);
goto exit;
}
ret = network_set_params(&net);
if (ret != HD_OK) {
printf("network_set_params fail=%d\n", ret);
goto exit;
}
ret = usr_alloc_input_mem(&net);
if (ret != HD_OK) {
printf("usr_alloc_input_mem fail=%d\n", ret);
goto exit;
}
ret = usr_alloc_output_mem(&net);
if (ret != HD_OK) {
printf("usr_alloc_output_mem fail=%d\n", ret);
goto exit;
}
while (1) // 持续推理
{
// 接收输入数据
ret = receive_data_via_socket(&net, sockfd);
#if 0
snprintf(test_list_path, STRING_LEN, "%s/test_list.txt", input_fold_path);
fd_test_list = fopen(test_list_path, "r");
if (!fd_test_list) {
printf("fopen(%s) fail\n", test_list_path);
ret = -1;
goto exit;
}
CHAR line[STRING_LEN];
printf("\n\n");
while(fscanf(fd_test_list,"%s", line) != EOF) {
CHAR temp_path[STRING_LEN];
snprintf(temp_path, STRING_LEN, "%s/%s", input_fold_path, line);
printf("%s...", temp_path);
#endif
// load input file and flush cache
ret = network_load_input(&net);
if (ret != HD_OK) {
printf("network_load_input fail=%d\n", ret);
goto exit;
}
input_cnt += 1;
for (UINT64 i = 0; i < proc_num; i++)
{
/* code */
ret = network_set_input(&net);
if (ret != HD_OK) {
printf("network_set_input fail=%d\n", ret);
goto exit;
}
ret = network_set_output(&net);
if (ret != HD_OK) {
printf("network_set_output fail=%d\n", ret);
goto exit;
}
gettimeofday(&tstart, NULL);
ret = network_proc(&net);
if (ret != HD_OK) {
printf("network_proc fail=%d\n", ret);
goto exit;
}
gettimeofday(&tend, NULL);
cur_time = (UINT64)(tend.tv_sec - tstart.tv_sec) * 1000000 + (tend.tv_usec - tstart.tv_usec);
if (i % dump_time_print_freq == 0)
{
printf("########process[%llu/%llu] cur time(us): %llu \r\n",i,proc_num,cur_time);
}
all_time += cur_time;
}
if (input_cnt % dump_mean_time == 0)
{
mean_time = (all_time / (proc_num * input_cnt));
printf("########inference [%u] datas mean time(us): %llu \r\n",input_cnt, mean_time);
}
// printf("network_proc [%llu] mean time: %llu us ... \n\r", proc_num,all_time / proc_num);
#if OUTPUT == 1
ret = network_get_output(&net);
if (ret != HD_OK) {
printf("network_get_output fail=%d\n", ret);
goto exit;
}
char *out_print = (char *)malloc(5000 * 4096); // 输出空间大小,2MB
//socket 发送输出结果
ret = send_data_via_socket(&net, sockfd, input_cnt, out_print);
if (ret != HD_OK) {
printf("send_data_via_socket fail=%d\n", ret);
}
free(out_print);
out_print = NULL;
#endif
#if 0
ret = network_get_output(&net);
if (ret != HD_OK) {
printf("network_get_output fail=%d\n", ret);
goto exit;
}
snprintf(temp_path, STRING_LEN, "%s/%s", output_fold_path, line);
ret = network_save_output(&net, temp_path);
if (ret != HD_OK) {
printf("network_save_output fail=%d\n", ret);
goto exit;
}
printf("done\n");
}
#endif
}
printf("over!\n");
exit:
usr_free_input_mem(&net);
usr_free_output_mem(&net);
ret = network_stop(&net);
if (ret != HD_OK) {
printf("network_stop fail=%d\n", ret);
//return ret;
}
ret = network_close(&net);
if (ret != HD_OK) {
printf("network_close fail=%d\n", ret);
//return ret;
}
ret = network_uninit();
if (ret != HD_OK) {
printf("network_init fail=%d\n", ret);
//return ret;
}
// if (fd_test_list) {
// fclose(fd_test_list);
// }
return ret;
}
int main(int argc, char *argv[])
{
HD_RESULT ret = HD_OK;
CHAR model_path[STRING_LEN];
// CHAR input_fold_path[STRING_LEN];
// CHAR output_fold_path[STRING_LEN];
HD_COMMON_MEM_INIT_CONFIG mem_cfg = {0};
// socket 初始化
int server_fd = setup_socket_server();
// 接收客户端连接
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_len);
if (client_fd < 0) {
perror("accept failed");
close(server_fd);
return 1;
}
printf("Client connected: %s\n", inet_ntoa(client_addr.sin_addr));
// init hdal
ret = hd_common_init(0);
if (ret != HD_OK) {
printf("hd_common_init fail=%d\n", ret);
goto exit;
}
// init mem
//#if defined(_BSP_NS02201_) || defined(_BSP_NS02302_)
ret = hd_common_mem_init(&mem_cfg);
if (HD_OK != ret) {
printf("hd_common_mem_init err: %d\r\n", ret);
goto exit;
}
//#endif
NET_DBG_DUMP_MODE debug_mode = 0;
// cmd: ai3_sample_list [model path] [proc_num] [debug_input_info] [debug_mode] [debug_dump_ut] [debug_dump_bw]
//*****************
// [debug_mode]
// NO_DBG = 0,
// NET_DBG_OUT_DUMP = 1,
// NET_DBG_TIME_DUMP = 2,
// NET_DBG_BW_DUMP = 3,
// NET_DBG_PERF_DUMP = 4,
//*****************
if (argc == 8) {
sscanf(argv[1], "%s", model_path);
printf("[model path]: %s\n", model_path);
proc_num = strtoull(argv[2], NULL, 10);
printf("[proc_num]: %llu\n", proc_num);
debug_input_info = atoi(argv[3]);
printf("[debug_input_info]: %d\n", debug_input_info);
debug_mode = atoi(argv[4]);
printf("[debug_mode]: %d\n", debug_mode);
debug_dump_ut = atoi(argv[5]);
printf("[debug_dump_ut]: %d\n", debug_dump_ut);
debug_dump_bw = atoi(argv[6]);
printf("[debug_dump_bw]: %d\n", debug_dump_bw);
dump_time_print_freq = strtoull(argv[7], NULL, 10);
printf("[dump_time_print_freq]: %llu\n", dump_time_print_freq);
} else {
printf("error: input param num must be 8 ! \n");
printf("[model path] [proc_num] [debug_input_info] [debug_mode] [debug_dump_ut] [debug_dump_bw] [dump_time_print_freq] \n");
}
if (debug_dump_ut)
{
// 執行 echo 命令
int result = system("echo ut 1 > /proc/kflow_ai/kcmd");
// 檢查執行結果
if (result == -1) {
// system 函數返回 -1 表示出錯
perror("system");
return 1;
}
}
if (debug_dump_bw)
{
// 執行 echo 命令
int result = system("echo w cfg 0 1000 > /proc/nvt_drv_sys/dram_info");
result = system("echo w start 0 1000 > /proc/nvt_drv_sys/dram_info");
if (result == -1) {
// system 函數返回 -1 表示出錯
perror("system");
return 1;
}
}
usleep(5000);
ret = run_ai_inference(model_path,debug_mode, client_fd);
if (ret != HD_OK) {
printf("run_ai_inference fail = %d\n", ret);
}
usleep(5000);
if (debug_dump_ut)
{
// 執行 echo 命令
int result = system("echo ut 0 > /proc/kflow_ai/kcmd");
if (result == -1) {
// system 函數返回 -1 表示出錯
perror("system");
return 1;
}
}
if (debug_dump_bw)
{
// 執行 echo 命令
int result = system("echo w stop 0 1000 > /proc/nvt_drv_sys/dram_info");
if (result == -1) {
// system 函數返回 -1 表示出錯
perror("system");
return 1;
}
}
exit:
ret = hd_common_mem_uninit();
if (ret != HD_OK) {
printf("mem fail=%d\n", ret);
}
usleep(300000);
ret = hd_common_uninit();
if (ret != HD_OK) {
printf("common fail=%d\n", ret);
}
// 关闭socket连接
close(client_fd);
close(server_fd);
return ret;
}
最新发布