恢复cat1_ws. 原始代码,为移植tcp_sample_manager接口做准备。
author孙春阳 <snickersun@163.com>
Sun, 10 Aug 2025 22:13:35 +0000 (06:13 +0800)
committer孙春阳 <snickersun@163.com>
Sun, 10 Aug 2025 22:13:35 +0000 (06:13 +0800)
code/sdk/application/brandy/brandy_standard/thread_pri_init.c
code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ai_server.cpp
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp
code/sdk/drivers/peripheral/slip/websocket_test.c
code/sdk/drivers/peripheral/slip/websocket_test.h

index 144ad20..6d38c30 100755 (executable)
@@ -498,8 +498,7 @@ uapi_pm_remove_sleep_veto(PM_ID_DEBUG);
 #endif
 
 #ifdef TCP_MANAGER_ENABLED
-    tcp_manager_test_init();
-    PRINT("TCP管理器测试模块初始化完成\n");
+    // tcp_manager_test_init();
 #endif
 
     uapi_custom_cmd_service_init();
index 0ccf6fc..a3380a9 100644 (file)
@@ -39,18 +39,6 @@ void lwip_close_websocket_client(WebSocketClient *client) ;
 int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code);\r
 int send_websocket_message(WebSocketClient *client, uint8_t *message, size_t message_len, WebSocketMessageType type) ;\r
 \r
-// === IO thread wrappers to ensure all socket operations are executed on a single thread ===\r
-// RX callback: invoked in IO thread context when data is read for a session\r
-typedef void (*ws_rx_callback_t)(WebSocketClient *client, const uint8_t *data, int len, WebSocketMessageType type, void *user);\r
-\r
-void ws_io_init(void);\r
-// Basic open (no RX callback; use ws_io_recv instead)\r
-WebSocketClient *ws_io_open(const char *url, const char *headers, uint8_t use_dns);\r
-// Extended open with RX callback (recommended)\r
-WebSocketClient *ws_io_open_ex(const char *url, const char *headers, uint8_t use_dns, ws_rx_callback_t cb, void *user);\r
-int ws_io_send(WebSocketClient *client, uint8_t *message, size_t message_len, WebSocketMessageType type);\r
-int ws_io_recv(WebSocketClient *client, unsigned char *buf, int len, WebSocketMessageType *code);\r
-void ws_io_close(WebSocketClient *client);\r
 \r
 #ifdef __cplusplus\r
 #if __cplusplus\r
index cdfe4f5..ac17fc3 100644 (file)
@@ -759,7 +759,7 @@ errcode_t chat_server_init(void)
     chat_taskcfg.create_queue_handle = NULL;
     chat_taskcfg.attr.name="chat_server_init";
     chat_taskcfg.attr.priority = TASK_PRIORITY_APP;
-    chat_taskcfg.attr.stack_size = 0x1000;
+    chat_taskcfg.attr.stack_size = 0x2000;
     chat_taskcfg.func = bk_websocket_demo;
     chat_taskcfg.use_mem = USE_EXTEND_MEM;
 
index d0443ea..c3bb844 100644 (file)
@@ -110,7 +110,9 @@ extern "C" {
 #include "mbedtls/sha1.h"
 
 
-
+#define BUFFER_SIZE 1024
+#define WEBSOCKET_KEY_LEN 24
+#define WEBSOCKET_GUID "1234567890123456"
 
 // #include "fs/fs.h"
 // #include "spiflash.h"
@@ -126,258 +128,6 @@ extern "C" {
 #include <stdint.h>
 #include <asm/delay.h>
 
-#include "msgqueue/osal_msgqueue.h"
-#include "semaphore/osal_semaphore.h"
-#include "bk_websocket.h"
-
-
-#define BUFFER_SIZE 1024
-#define WEBSOCKET_KEY_LEN 25
-#define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-
-// IO thread and command queue to serialize all socket operations
-typedef enum {
-    WS_CMD_OPEN,
-    WS_CMD_SEND,
-    WS_CMD_RECV,
-    WS_CMD_CLOSE
-} ws_cmd_type_t;
-
-typedef struct {
-    ws_cmd_type_t cmd;
-    // input args
-    const char *url;
-    const char *headers;
-    uint8_t use_dns;
-    WebSocketClient *client;
-    uint8_t *tx;
-    size_t tx_len;
-    WebSocketMessageType tx_type;
-    unsigned char *rx;
-    int rx_len;
-    WebSocketMessageType *rx_type;
-    // completion
-    int result_int;
-    WebSocketClient *result_client;
-    osal_semaphore sem; // completion semaphore
-} ws_cmd_t;
-
-// Per-session RX callback registration
-typedef struct {
-    WebSocketClient *client;
-    ws_rx_callback_t rx_cb;
-    void *user;
-} ws_session_t;
-
-#define WS_MAX_SESSIONS 8
-static ws_session_t g_ws_sessions[WS_MAX_SESSIONS];
-
-static unsigned long g_ws_queue_id = 0;
-static osThreadId_t g_ws_io_thread = NULL;
-
-static void ws_cmd_init(ws_cmd_t *cmd)
-{
-    memset(cmd, 0, sizeof(*cmd));
-    (void)osal_sem_init(&cmd->sem, 0);
-}
-
-static void ws_cmd_deinit(ws_cmd_t *cmd)
-{
-    osal_sem_destroy(&cmd->sem);
-}
-
-static void ws_sessions_init(void)
-{
-    memset(g_ws_sessions, 0, sizeof(g_ws_sessions));
-}
-
-static int ws_sessions_add(WebSocketClient *c, ws_rx_callback_t cb, void *user)
-{
-    for (int i = 0; i < WS_MAX_SESSIONS; ++i) {
-        if (g_ws_sessions[i].client == NULL) {
-            g_ws_sessions[i].client = c;
-            g_ws_sessions[i].rx_cb = cb;
-            g_ws_sessions[i].user = user;
-            return 0;
-        }
-    }
-    return -1;
-}
-
-static void ws_sessions_remove(WebSocketClient *c)
-{
-    for (int i = 0; i < WS_MAX_SESSIONS; ++i) {
-        if (g_ws_sessions[i].client == c) {
-            memset(&g_ws_sessions[i], 0, sizeof(g_ws_sessions[i]));
-            return;
-        }
-    }
-}
-
-static ws_session_t *ws_sessions_find(WebSocketClient *c)
-{
-    for (int i = 0; i < WS_MAX_SESSIONS; ++i) {
-        if (g_ws_sessions[i].client == c) {
-            return &g_ws_sessions[i];
-        }
-    }
-    return NULL;
-}
-
-static void ws_io_thread_entry(void *arg)
-{
-    (void)arg;
-    while (1) {
-        // Process next command if available; else try to poll RX on active sessions
-        ws_cmd_t *cmd_ptr = NULL;
-        unsigned int msg_size = sizeof(cmd_ptr);
-        if (osal_msg_queue_read_copy(g_ws_queue_id, &cmd_ptr, &msg_size, 10) == OSAL_SUCCESS && cmd_ptr != NULL) {
-            switch (cmd_ptr->cmd) {
-                case WS_CMD_OPEN:
-                    cmd_ptr->result_client = init_websocket_client(cmd_ptr->url, cmd_ptr->headers, cmd_ptr->use_dns);
-                    cmd_ptr->result_int = (cmd_ptr->result_client != NULL) ? 0 : -1;
-                    break;
-                case WS_CMD_SEND:
-                    cmd_ptr->result_int = send_websocket_message(cmd_ptr->client, cmd_ptr->tx, cmd_ptr->tx_len, cmd_ptr->tx_type);
-                    break;
-                case WS_CMD_RECV:
-                    cmd_ptr->result_int = receive_websocket_message(cmd_ptr->client, cmd_ptr->rx, cmd_ptr->rx_len, cmd_ptr->rx_type);
-                    break;
-                case WS_CMD_CLOSE:
-                    lwip_close_websocket_client(cmd_ptr->client);
-                    ws_sessions_remove(cmd_ptr->client);
-                    cmd_ptr->result_int = 0;
-                    break;
-                default:
-                    cmd_ptr->result_int = -1;
-                    break;
-            }
-            osal_sem_up(&cmd_ptr->sem);
-            continue;
-        }
-        // No command -> build fd_set and wait for readable sockets
-        fd_set rfds; FD_ZERO(&rfds);
-        int maxfd = -1; int active = 0;
-        for (int i = 0; i < WS_MAX_SESSIONS; ++i) {
-            ws_session_t *s = &g_ws_sessions[i];
-            if (s->client == NULL || s->rx_cb == NULL) continue;
-            FD_SET(s->client->sockfd, &rfds);
-            if (s->client->sockfd > maxfd) maxfd = s->client->sockfd;
-            active++;
-        }
-        if (active == 0 || maxfd < 0) {
-            // nothing to poll
-            continue;
-        }
-        struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 20000; // 20ms
-        int ready = lwip_select(maxfd + 1, &rfds, NULL, NULL, &tv);
-        if (ready <= 0) {
-            continue;
-        }
-        for (int i = 0; i < WS_MAX_SESSIONS; ++i) {
-            ws_session_t *s = &g_ws_sessions[i];
-            if (s->client == NULL || s->rx_cb == NULL) continue;
-            if (!FD_ISSET(s->client->sockfd, &rfds)) continue;
-            WebSocketMessageType type;
-            uint8_t buf[1024];
-            int n = receive_websocket_message(s->client, buf, sizeof(buf), &type);
-            if (n > 0) {
-                s->rx_cb(s->client, buf, n, type, s->user);
-            }
-        }
-    }
-}
-
-void ws_io_init(void)
-{
-    if (g_ws_queue_id == 0) {
-        (void)osal_msg_queue_create("ws_io_q", 16, &g_ws_queue_id, 0, sizeof(ws_cmd_t *));
-    }
-    if (g_ws_io_thread == NULL) {
-        osThreadAttr_t attr; memset(&attr, 0, sizeof(attr)); attr.name = "ws_io"; attr.stack_size = 4096; attr.priority = osPriorityNormal;
-        ws_sessions_init();
-        g_ws_io_thread = osThreadNew(ws_io_thread_entry, NULL, &attr);
-    }
-}
-
-static int ws_enqueue_and_wait(ws_cmd_t *cmd)
-{
-    ws_cmd_t *ptr = cmd;
-    if (osal_msg_queue_write_copy(g_ws_queue_id, &ptr, sizeof(ptr), OSAL_MSGQ_WAIT_FOREVER) != OSAL_SUCCESS) {
-        return -1;
-    }
-    (void)osal_sem_down(&cmd->sem);
-    return 0;
-}
-
-WebSocketClient *ws_io_open(const char *url, const char *headers, uint8_t use_dns)
-{
-    ws_cmd_t cmd; ws_cmd_init(&cmd);
-    cmd.cmd = WS_CMD_OPEN;
-    cmd.url = url;
-    cmd.headers = headers;
-    cmd.use_dns = use_dns;
-    if (ws_enqueue_and_wait(&cmd) != 0) {
-        ws_cmd_deinit(&cmd);
-        return NULL;
-    }
-    WebSocketClient *cli = cmd.result_client;
-    ws_cmd_deinit(&cmd);
-    return cli;
-}
-
-WebSocketClient *ws_io_open_ex(const char *url, const char *headers, uint8_t use_dns, ws_rx_callback_t cb, void *user)
-{
-    WebSocketClient *cli = ws_io_open(url, headers, use_dns);
-    if (cli && cb) {
-        (void)ws_sessions_add(cli, cb, user);
-    }
-    return cli;
-}
-
-int ws_io_send(WebSocketClient *client, uint8_t *message, size_t message_len, WebSocketMessageType type)
-{
-    ws_cmd_t cmd; ws_cmd_init(&cmd);
-    cmd.cmd = WS_CMD_SEND;
-    cmd.client = client;
-    cmd.tx = message;
-    cmd.tx_len = message_len;
-    cmd.tx_type = type;
-    if (ws_enqueue_and_wait(&cmd) != 0) {
-        ws_cmd_deinit(&cmd);
-        return -1;
-    }
-    int ret = cmd.result_int;
-    ws_cmd_deinit(&cmd);
-    return ret;
-}
-
-int ws_io_recv(WebSocketClient *client, unsigned char *buf, int len, WebSocketMessageType *code)
-{
-    ws_cmd_t cmd; ws_cmd_init(&cmd);
-    cmd.cmd = WS_CMD_RECV;
-    cmd.client = client;
-    cmd.rx = buf;
-    cmd.rx_len = len;
-    cmd.rx_type = code;
-    if (ws_enqueue_and_wait(&cmd) != 0) {
-        ws_cmd_deinit(&cmd);
-        return -1;
-    }
-    int ret = cmd.result_int;
-    ws_cmd_deinit(&cmd);
-    return ret;
-}
-
-void ws_io_close(WebSocketClient *client)
-{
-    ws_cmd_t cmd; ws_cmd_init(&cmd);
-    cmd.cmd = WS_CMD_CLOSE;
-    cmd.client = client;
-    (void)ws_enqueue_and_wait(&cmd);
-    ws_cmd_deinit(&cmd);
-}
-
 
 extern osStatus_t osDelay(uint32_t ticks);
 #define cat1_msleep(ms) LOS_Msleep(ms) /* osDelay(1) : 1ms */
@@ -620,15 +370,23 @@ static uint64_t ntohll(uint64_t netlonglong) {
 }
 // 生成随机的 WebSocket 密钥
 void generate_websocket_key(char *key) {
-    unsigned char raw[16];
-    for (int i = 0; i < 16; ++i) {
-        raw[i] = (unsigned char)(rand() & 0xFF);
-    }
-    size_t olen = 0;
-    mbedtls_base64_encode((unsigned char *)key, WEBSOCKET_KEY_LEN, &olen, raw, sizeof(raw));
-    if (olen >= WEBSOCKET_KEY_LEN) {
-        olen = WEBSOCKET_KEY_LEN - 1;
+    static const char charset[] =
+        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    for (int i = 0; i < WEBSOCKET_KEY_LEN - 1; ++i) {
+        key[i] = charset[rand() % (sizeof(charset) - 1)];
     }
+    key[WEBSOCKET_KEY_LEN - 1] = '\0';
+
+    unsigned char encoded[WEBSOCKET_KEY_LEN * 2];
+    size_t olen;
+    mbedtls_base64_encode(encoded, sizeof(encoded), &olen, (const unsigned char *)key, strlen(key));
+    printf("generate_websocket_key %s %d\r\n",encoded ,olen);
+
+    if(olen>=(WEBSOCKET_KEY_LEN-1))
+    olen=WEBSOCKET_KEY_LEN-1;
+
+    strncpy(key, (const char *)encoded, olen);
+
     key[olen] = '\0';
 }
 
@@ -643,7 +401,7 @@ void generate_accept_key(const char *key, char *accept_key) {
 
     unsigned char encoded[64];
     size_t olen;
-    mbedtls_base64_encode(encoded, sizeof(encoded), &olen, sha1_result, sizeof(sha1_result));
+    mbedtls_base64_encode(encoded, sizeof(encoded), &olen, sha1_result, 16);//sizeof(sha1_result));
     strncpy(accept_key, (const char *)encoded, olen);
     accept_key[olen] = '\0';
 }
@@ -668,7 +426,7 @@ int send_handshake(WebSocketClient *client,const char *headers) {
     if(headers!= NULL)
     {
         snprintf(request, BUFFER_SIZE,
-            "GET /%s%s%s HTTP/1.1\r\n"
+            "GET /%s?%s HTTP/1.1\r\n"
             "Host: %s:%d\r\n"
             "Upgrade: websocket\r\n"
             "Connection: Upgrade\r\n"
@@ -677,11 +435,11 @@ int send_handshake(WebSocketClient *client,const char *headers) {
             "Origin: http://%s:%d\r\n"
             "%s\r\n"
             "\r\n",
-            client->path ? client->path : "", (client->query?"?":""), (client->query?client->query:"") ,client->host,client->port, key,client->host,client->port,headers);
+            client->path,client->query  ,client->host,client->port, accept_key,client->host,client->port,headers);
     }else
     {
         snprintf(request, BUFFER_SIZE,
-            "GET /%s%s%s HTTP/1.1\r\n"
+            "GET /%s?%s HTTP/1.1\r\n"
             "Host: %s:%d\r\n"
             "Upgrade: websocket\r\n"
             "Connection: Upgrade\r\n"
@@ -689,7 +447,7 @@ int send_handshake(WebSocketClient *client,const char *headers) {
             "Sec-WebSocket-Version: 13\r\n"
             "Origin: http://%s:%d\r\n"
             "\r\n",
-            client->path ? client->path : "", (client->query?"?":""), (client->query?client->query:"") , client->host,client->port, key,client->host,client->port);
+            client->path,client->query , client->host,client->port, accept_key,client->host,client->port);
     }
     
     printf("send_handshake request:\r\n%s",request);
@@ -961,10 +719,8 @@ static void dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
 {
     struct cat1_ws_init_t * ip_sem=(struct cat1_ws_init_t *)arg;
 
-    printf("hostname %s\r\n", hostname);
-    if (ipaddr != NULL) {
-        memcpy(&(ip_sem->ip), ipaddr, sizeof(*ipaddr));
-    }
+    printf("hostname %s ipaddr%d \r\n",hostname,ipaddr->u_addr.ip4);
+    memcpy(&(ip_sem->ip),ipaddr,sizeof(ipaddr));
     (void)osSemaphoreRelease(ip_sem->dns_done_sem);
 }
 
@@ -1017,28 +773,20 @@ WebSocketClient *init_websocket_client(const char *url, const char *headers,uint
    // printf("init_websocket_client 3\n");
     if(use_dns)
     {
-        // If host is numeric IP, bypass DNS
-        if (inet_aton(parsed_url.host, &in_addr_t)) {
-            memcpy(&server_addr.sin_addr, &in_addr_t, sizeof(in_addr_t));
-        } else {
-            ip_sem.dns_done_sem= osSemaphoreNew(1, 0, NULL);
-            if(ip_sem.dns_done_sem==0)
-            {
-                goto client_ERROR;
-            }
+        ip_sem.dns_done_sem= osSemaphoreNew(1, 0, NULL);
+        if(ip_sem.dns_done_sem==0)
+        {
+            goto client_ERROR;
+        }
 
-            ret = dns_gethostbyname(parsed_url.host, &ip, dns_found, &ip_sem);
-            if (ret == ERR_OK) {
-                memcpy(&server_addr.sin_addr.s_addr, &ip.u_addr.ip4, 4);
-            } else if (ret == ERR_INPROGRESS) {
-                osSemaphoreAcquire(ip_sem.dns_done_sem, 1000*30);
-                memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4);
-            } else {
-                osSemaphoreDelete(ip_sem.dns_done_sem);
-                goto client_ERROR;
-            }
-            osSemaphoreDelete(ip_sem.dns_done_sem);
+        ret =dns_gethostbyname(parsed_url.host,&ip,dns_found,&ip_sem);
+        // if(ERR_OK==ret)
+        {
+            osSemaphoreAcquire(ip_sem.dns_done_sem, 1000*30);
         }
+        osSemaphoreDelete(ip_sem.dns_done_sem);
+        printf("dns_gethostbyname %d\r\n",ip_sem.ip.u_addr.ip4);
+        memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4);
 
     }
     else
index 1fbdec2..d73e7ce 100644 (file)
@@ -2,7 +2,6 @@
  * WebSocket测试程序
  * 基于LiteOS-M系统
  * 通过AT^TESTWEBSOCKET命令执行测试
- * 支持多线程并发测试同一服务器
  */
 
 #ifdef SUPPORT_WEBSOCKET_TEST
@@ -24,49 +23,23 @@ extern "C" {
 
 // 测试配置
 #define TEST_DATA_SIZE 228
-#define MAX_TEST_COUNT 100000
+#define MAX_TEST_COUNT 1000
 #define THREAD_STACK_SIZE 4096
 #define THREAD_PRIORITY 10
-#define MAX_CONCURRENT_THREADS 16
-#define MAX_CONCURRENT_CONNECTIONS 8
-
-// Queue message for received frames via IO thread callback
-typedef struct {
-    WebSocketMessageType type;
-    int len;
-    uint8_t data[TEST_DATA_SIZE];
-    uint32_t thread_id;  // 标识来自哪个线程
-} ws_msg_t;
-
-static osMessageQueueId_t g_ws_rx_queue = NULL;
-
-// 线程信息结构
-typedef struct {
-    osThreadId_t thread_id;
-    uint32_t thread_index;
-    WebSocketClient *client;
-    bool active;
-    uint32_t send_count;
-    uint32_t recv_count;
-    uint32_t lost_count;
-    uint8_t expected_data[TEST_DATA_SIZE];
-    uint8_t received_data[TEST_DATA_SIZE];
-    osMutexId_t thread_mutex;
-} test_thread_info_t;
 
 // 全局变量
+static osThreadId_t send_thread_id = NULL;
+static osThreadId_t recv_thread_id = NULL;
 static osMutexId_t test_mutex = NULL;
 static osSemaphoreId_t test_semaphore = NULL;
-static osTimerId_t test_timer = NULL;
 
-static test_thread_info_t test_threads[MAX_CONCURRENT_THREADS] = {0};
-static uint32_t active_thread_count = 0;
+static WebSocketClient *test_client = NULL;
 static bool test_running = false;
-static uint32_t total_send_count = 0;
-static uint32_t total_recv_count = 0;
-static uint32_t total_lost_count = 0;
-static uint32_t test_duration_ms = 0;
-static uint32_t test_start_time = 0;
+static uint32_t send_count = 0;
+static uint32_t recv_count = 0;
+static uint32_t lost_count = 0;
+static uint8_t expected_data[TEST_DATA_SIZE];
+static uint8_t received_data[TEST_DATA_SIZE];
 
 // 测试状态
 typedef enum {
@@ -79,151 +52,151 @@ typedef enum {
 static test_state_t test_state = TEST_STATE_IDLE;
 
 // 函数声明
-static void websocket_test_thread(void *argument);
-static bool init_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms);
+static void websocket_send_thread(void *argument);
+static void websocket_recv_thread(void *argument);
+static bool init_websocket_test(const char *server_addr, uint16_t port);
 static void cleanup_websocket_test(void);
-static bool send_test_data(test_thread_info_t *thread_info, uint8_t data_value);
-static bool receive_test_data(test_thread_info_t *thread_info, uint8_t *data_value);
+static bool send_test_data(uint8_t data_value);
+static bool receive_test_data(uint8_t *data_value);
 static void print_test_results(void);
 static void check_memory_status(void);
-static void test_timer_callback(void *argument);
-static void cleanup_thread_resources(test_thread_info_t *thread_info);
-
-static void ws_on_rx(WebSocketClient *client, const uint8_t *data, int len, WebSocketMessageType type, void *user)
-{
-    if (g_ws_rx_queue == NULL || data == NULL || len <= 0 || user == NULL) {
-        return;
-    }
-    
-    test_thread_info_t *thread_info = (test_thread_info_t *)user;
-    ws_msg_t msg;
-    msg.type = type;
-    msg.len = (len > TEST_DATA_SIZE) ? TEST_DATA_SIZE : len;
-    msg.thread_id = thread_info->thread_index;
-    memcpy(msg.data, data, (size_t)msg.len);
-    
-    // 快速入队,避免阻塞IO线程
-    osStatus_t result = osMessageQueuePut(g_ws_rx_queue, &msg, 0, 0);
-    if (result != osOK) {
-        WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "接收队列满,丢弃消息");
-    }
-}
 
 /**
- * WebSocket测试线程(每个线程独立处理一个连接)
+ * WebSocket发送线程
  */
-static void websocket_test_thread(void *argument)
+static void websocket_send_thread(void *argument)
 {
-    test_thread_info_t *thread_info = (test_thread_info_t *)argument;
-    if (!thread_info) {
-        return;
-    }
-    
     uint8_t data_value = 0;
     uint32_t send_interval = 100; // 100ms间隔
     uint32_t error_count = 0;
-    uint32_t thread_id = thread_info->thread_index;
     
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试线程[%u]启动", thread_id);
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket发送线程启动");
     
-    while (test_running && thread_info->active) {
+    while (test_running) {
         // 检查客户端是否有效
-        if (!thread_info->client || thread_info->client->sockfd < 0) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 客户端无效", thread_id);
+        if (!test_client || test_client->sockfd < 0) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送线程: 客户端无效");
             break;
         }
         
-        // 发送测试数据
-        if (send_test_data(thread_info, data_value)) {
-            thread_info->send_count++;
-            total_send_count++;
-            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送数据包 %u, 值: %u", 
-                         thread_id, thread_info->send_count, data_value);
+        if (send_test_data(data_value)) {
+            send_count++;
+            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送数据包 %u, 值: %u", send_count, data_value);
             data_value = (data_value + 1) % 256; // 0-255循环
             error_count = 0; // 重置错误计数
         } else {
             error_count++;
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送测试数据失败, 错误计数: %u", 
-                         thread_id, error_count);
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送测试数据失败, 错误计数: %u", error_count);
             
             // 如果连续失败超过5次,退出循环
             if (error_count > 5) {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 连续失败次数过多,退出", thread_id);
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送线程: 连续失败次数过多,退出");
                 break;
             }
         }
         
-        // 接收测试数据
-        uint8_t received_value;
-        if (receive_test_data(thread_info, &received_value)) {
-            thread_info->recv_count++;
-            total_recv_count++;
-            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据包 %u, 值: %u", 
-                         thread_id, thread_info->recv_count, received_value);
+        // 检查是否需要停止
+        if (!test_running) {
+            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送线程: 收到停止信号");
+            break;
+        }
+        
+        osDelay(send_interval);
+    }
+    
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket发送线程结束");
+    return;
+}
+
+/**
+ * WebSocket接收线程
+ */
+static void websocket_recv_thread(void *argument)
+{
+    uint8_t data_value = 0;
+    uint32_t timeout_count = 0;
+    uint32_t error_count = 0;
+    
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket接收线程启动");
+    
+    while (test_running) {
+        // 检查客户端是否有效
+        if (!test_client || test_client->sockfd < 0) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收线程: 客户端无效");
+            break;
+        }
+        
+        if (receive_test_data(&data_value)) {
+            recv_count++;
+            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收数据包 %u, 值: %u", recv_count, data_value);
             
             // 检查数据是否正确
             bool data_correct = true;
             for (int i = 0; i < TEST_DATA_SIZE; i++) {
-                if (thread_info->received_data[i] != received_value) {
+                if (received_data[i] != data_value) {
                     data_correct = false;
                     break;
                 }
             }
             
             if (!data_correct) {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据验证失败", thread_id);
-                thread_info->lost_count++;
-                total_lost_count++;
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据验证失败");
+                lost_count++;
+            }
+            
+            timeout_count = 0;
+            error_count = 0; // 重置错误计数
+        } else {
+            timeout_count++;
+            error_count++;
+            if (timeout_count > 10) { // 1秒超时
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据超时");
+                break;
+            }
+            
+            // 如果连续错误超过20次,退出循环
+            if (error_count > 20) {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收线程: 连续错误次数过多,退出");
+                break;
             }
         }
         
         // 检查是否需要停止
-        if (!test_running || !thread_info->active) {
-            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 收到停止信号", thread_id);
+        if (!test_running) {
+            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收线程: 收到停止信号");
             break;
         }
         
-        osDelay(send_interval);
+        osDelay(100);
     }
     
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocketæµ\8bè¯\95线ç¨\8b[%u]ç»\93æ\9d\9f", thread_id);
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocketæ\8e¥æ\94¶çº¿ç¨\8bç»\93æ\9d\9f");
     return;
 }
 
 /**
  * 初始化WebSocket测试
  */
-static bool init_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms)
+static bool init_websocket_test(const char *server_addr, uint16_t port)
 {
-    if (thread_count > MAX_CONCURRENT_THREADS) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程数超过最大限制: %u > %u", thread_count, MAX_CONCURRENT_THREADS);
-        return false;
-    }
+    char url[256];
+    snprintf(url, sizeof(url), "ws://%s:%d/", server_addr, port);
+    
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "连接WebSocket服务器: %s", url);
     
-    if (thread_count > MAX_CONCURRENT_CONNECTIONS) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接数超过最大限制: %u > %u", thread_count, MAX_CONCURRENT_CONNECTIONS);
+    // 创建WebSocket客户端
+    test_client = init_websocket_client(url, NULL, 1); // 启用DNS解析
+    if (test_client == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket客户端创建失败");
         return false;
     }
     
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "初始化WebSocket测试: %s:%u, 线程数: %u, 持续时间: %u ms", 
-                  server_addr, port, thread_count, duration_ms);
-    
-    // 初始化单线程IO调度
-    ws_io_init();
-
-    // 创建接收消息队列(供回调快速入队,接收线程取出处理)
-    if (g_ws_rx_queue == NULL) {
-        g_ws_rx_queue = osMessageQueueNew(thread_count * 32, sizeof(ws_msg_t), NULL);
-        if (g_ws_rx_queue == NULL) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "创建接收队列失败");
-            return false;
-        }
-    }
-
     // 创建互斥锁
     test_mutex = osMutexNew(NULL);
     if (test_mutex == NULL) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "互斥锁创建失败");
+        lwip_close_websocket_client(test_client);
+        test_client = NULL;
         return false;
     }
     
@@ -232,85 +205,42 @@ static bool init_websocket_test(const char *server_addr, uint16_t port, uint32_t
     if (test_semaphore == NULL) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "信号量创建失败");
         osMutexDelete(test_mutex);
+        lwip_close_websocket_client(test_client);
+        test_client = NULL;
         return false;
     }
     
-    // 初始化测试线程信息
-    memset(test_threads, 0, sizeof(test_threads));
-    active_thread_count = thread_count;
-    
-    // 为每个线程创建WebSocket连接
-    for (uint32_t i = 0; i < thread_count; i++) {
-        test_thread_info_t *thread_info = &test_threads[i];
-        thread_info->thread_index = i;
-        thread_info->active = false;
-        thread_info->send_count = 0;
-        thread_info->recv_count = 0;
-        thread_info->lost_count = 0;
-        
-        // 创建线程互斥锁
-        thread_info->thread_mutex = osMutexNew(NULL);
-        if (thread_info->thread_mutex == NULL) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]互斥锁创建失败", i);
-            cleanup_websocket_test();
-            return false;
-        }
-        
-        // 创建WebSocket客户端(在IO线程中,并注册回调)
-        char url[256];
-        snprintf(url, sizeof(url), "ws://%s:%u/", server_addr, port);
-        
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 连接WebSocket服务器: %s", i, url);
-        
-        thread_info->client = ws_io_open_ex(url, NULL, ws_on_rx, thread_info);
-        if (thread_info->client == NULL) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: WebSocket客户端创建失败", i);
-            cleanup_websocket_test();
-            return false;
-        }
-        
-        // 创建测试线程
-        osThreadAttr_t thread_attr = {
-            .name = "websocket_test",
-            .stack_size = THREAD_STACK_SIZE,
-            .priority = osPriorityNormal,
-        };
-        
-        char thread_name[32];
-        snprintf(thread_name, sizeof(thread_name), "ws_test_%u", i);
-        thread_attr.name = thread_name;
-        
-        thread_info->thread_id = osThreadNew(websocket_test_thread, thread_info, &thread_attr);
-        if (thread_info->thread_id == NULL) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 测试线程创建失败", i);
-            cleanup_websocket_test();
-            return false;
-        }
-        
-        thread_info->active = true;
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 初始化完成", i);
-    }
-    
-    // 设置运行标志
+    // 设置运行标志(在创建线程之前)
     test_running = true;
     test_state = TEST_STATE_RUNNING;
-    test_duration_ms = duration_ms;
-    test_start_time = osKernelGetTickCount();
     
-    // 如果指定了持续时间,创建定时器
-    if (duration_ms > 0) {
-        test_timer = osTimerNew(test_timer_callback, osTimerOnce, NULL, NULL);
-        if (test_timer == NULL) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试定时器创建失败");
-            cleanup_websocket_test();
-            return false;
-        }
-        
-        osTimerStart(test_timer, duration_ms);
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试定时器已启动,%u ms后自动停止", duration_ms);
+    // 创建发送线程
+    osThreadAttr_t send_attr = {
+        .name = "websocket_send",
+        .stack_size = THREAD_STACK_SIZE,
+        .priority = osPriorityNormal,
+    };
+    send_thread_id = osThreadNew(websocket_send_thread, NULL, &send_attr);
+    if (send_thread_id == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送线程创建失败");
+        cleanup_websocket_test();
+        return false;
+    }
+    
+    // 创建接收线程
+    osThreadAttr_t recv_attr = {
+        .name = "websocket_recv",
+        .stack_size = THREAD_STACK_SIZE,
+        .priority = osPriorityNormal,
+    };
+    recv_thread_id = osThreadNew(websocket_recv_thread, NULL, &recv_attr);
+    if (recv_thread_id == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收线程创建失败");
+        cleanup_websocket_test();
+        return false;
     }
     
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试初始化成功,%u个线程已启动", thread_count);
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试初始化成功");
     return true;
 }
 
@@ -324,35 +254,27 @@ static void cleanup_websocket_test(void)
     // 首先停止运行标志
     test_running = false;
     
-    // 停止定时器
-    if (test_timer) {
-        osTimerStop(test_timer);
-        osTimerDelete(test_timer);
-        test_timer = NULL;
-    }
-    
     // 等待一段时间让线程自然结束
-    osDelay(200);
-    
-    // 安全地等待所有线程结束
-    for (uint32_t i = 0; i < active_thread_count; i++) {
-        test_thread_info_t *thread_info = &test_threads[i];
-        if (thread_info->thread_id && thread_info->active) {
-            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待线程[%u]结束", i);
-            osThreadJoin(thread_info->thread_id);
-            thread_info->thread_id = NULL;
-        }
+    osDelay(100);
+    
+    // 安全地等待线程结束
+    if (send_thread_id) {
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待发送线程结束");
+        osThreadJoin(send_thread_id);
+        send_thread_id = NULL;
     }
     
-    // 清理线程资源
-    for (uint32_t i = 0; i < active_thread_count; i++) {
-        cleanup_thread_resources(&test_threads[i]);
+    if (recv_thread_id) {
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待接收线程结束");
+        osThreadJoin(recv_thread_id);
+        recv_thread_id = NULL;
     }
     
-    // 关闭接收队列
-    if (g_ws_rx_queue) {
-        osMessageQueueDelete(g_ws_rx_queue);
-        g_ws_rx_queue = NULL;
+    // 关闭WebSocket连接 - 在删除线程相关资源之前
+    if (test_client) {
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "关闭WebSocket连接");
+        lwip_close_websocket_client(test_client);
+        test_client = NULL;
     }
     
     // 删除信号量
@@ -361,132 +283,103 @@ static void cleanup_websocket_test(void)
         test_semaphore = NULL;
     }
     
-    // 删除互斥锁
+    // 删除互斥锁 - 最后删除
     if (test_mutex) {
         osMutexDelete(test_mutex);
         test_mutex = NULL;
     }
     
-    active_thread_count = 0;
     test_state = TEST_STATE_IDLE;
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试清理完成");
 }
 
-/**
- * 清理单个线程的资源
- */
-static void cleanup_thread_resources(test_thread_info_t *thread_info)
-{
-    if (!thread_info) {
-        return;
-    }
-    
-    // 关闭WebSocket连接
-    if (thread_info->client) {
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 关闭WebSocket连接", thread_info->thread_index);
-        ws_io_close(thread_info->client);
-        thread_info->client = NULL;
-    }
-    
-    // 删除线程互斥锁
-    if (thread_info->thread_mutex) {
-        osMutexDelete(thread_info->thread_mutex);
-        thread_info->thread_mutex = NULL;
-    }
-    
-    // 重置线程信息
-    thread_info->active = false;
-    thread_info->send_count = 0;
-    thread_info->recv_count = 0;
-    thread_info->lost_count = 0;
-}
-
 /**
  * 发送测试数据
  */
-static bool send_test_data(test_thread_info_t *thread_info, uint8_t data_value)
+static bool send_test_data(uint8_t data_value)
 {
-    if (!thread_info || !thread_info->client || !test_running || !thread_info->active) {
+    if (!test_client || !test_running) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 客户端或运行状态无效");
         return false;
     }
     
     // 添加额外的安全检查
-    if (thread_info->client->sockfd < 0) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送数据失败: 无效的socket", thread_info->thread_index);
+    if (test_client->sockfd < 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 无效的socket");
         return false;
     }
     
+    // 验证测试数据缓冲区 - 数组地址总是为true,不需要检查
+    // if (!expected_data) {
+    //     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 测试数据缓冲区无效");
+    //     return false;
+    // }
+    
     // 准备测试数据
-    memset(thread_info->expected_data, data_value, TEST_DATA_SIZE);
+    memset(expected_data, data_value, TEST_DATA_SIZE);
+    
+    // 添加内存检查
+    if (TEST_DATA_SIZE > 65536) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 数据大小过大");
+        return false;
+    }
+    
+    // 检查内存状态
+    check_memory_status();
     
     // 发送数据前增加延迟,避免过于频繁的发送
     osDelay(5);
     
-    // 发送数据 - 通过IO线程,确保线程安全
-    int result = ws_io_send(thread_info->client, thread_info->expected_data, TEST_DATA_SIZE, WS_BINARY);
+    // 发送数据
+    int result = send_websocket_message(test_client, expected_data, TEST_DATA_SIZE, WS_BINARY);
     if (result != 0) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送数据失败: %d", thread_info->thread_index, result);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: %d", result);
         return false;
     }
     
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送数据成功: 值=%u, 大小=%d", data_value, TEST_DATA_SIZE);
     return true;
 }
 
 /**
  * 接收测试数据
  */
-static bool receive_test_data(test_thread_info_t *thread_info, uint8_t *data_value)
+static bool receive_test_data(uint8_t *data_value)
 {
-    if (!thread_info || !test_running || !thread_info->active || !data_value) {
+    if (!test_client || !test_running) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据失败: 客户端或运行状态无效");
         return false;
     }
     
-    if (g_ws_rx_queue == NULL) {
-        return false;
-    }
-    
-    ws_msg_t msg;
-    uint8_t prio = 0;
-    osStatus_t st = osMessageQueueGet(g_ws_rx_queue, &msg, &prio, 50); // 减少超时时间,提高响应性
-    if (st != osOK) {
-        return false; // 超时或无数据
-    }
+    WebSocketMessageType type;
+    int result = receive_websocket_message(test_client, received_data, TEST_DATA_SIZE, &type);
     
-    // 检查消息是否属于当前线程
-    if (msg.thread_id != thread_info->thread_index) {
-        // 重新放回队列,让正确的线程处理
-        osMessageQueuePut(g_ws_rx_queue, &msg, 0, 0);
+    if (result <= 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据失败: result=%d", result);
         return false;
     }
     
-    if (msg.type != WS_BINARY) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据类型错误: type=%d", 
-                     thread_info->thread_index, msg.type);
+    if (type != WS_BINARY) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据类型错误: type=%d", type);
         return false;
     }
     
-    if (msg.len != TEST_DATA_SIZE) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据大小错误: %d", 
-                     thread_info->thread_index, msg.len);
+    // 检查数据大小
+    if (result != TEST_DATA_SIZE) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据大小错误: %d", result);
         return false;
     }
     
-    memcpy(thread_info->received_data, msg.data, TEST_DATA_SIZE);
-    *data_value = thread_info->received_data[0];
+    // 提取数据值
+    *data_value = received_data[0];
     
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收数据成功: 值=%u, 大小=%d", *data_value, result);
     return true;
 }
 
 /**
- * æµ\8bè¯\95å®\9aæ\97¶å\99¨å\9b\9eè°\83
+ * æ\89\93å\8d°æµ\8bè¯\95ç»\93æ\9e\9c
  */
-static void test_timer_callback(void *argument)
-{
-    (void)argument;
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试定时器触发,自动停止测试");
-    stop_websocket_test();
-}
-
 /**
  * 检查内存状态
  */
@@ -495,8 +388,22 @@ static void check_memory_status(void)
     // 检查内存状态
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket: 检查内存状态");
     
+    // 检查内存池状态 - 暂时注释掉,避免编译错误
+    // extern void ws_mem_pool_status(void);
+    // ws_mem_pool_status();
+    
+    // 检查系统内存状态 - 暂时注释掉,避免编译错误
+    // extern size_t xPortGetFreeHeapSize(void);
+    // size_t free_heap = xPortGetFreeHeapSize();
+    // WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket: 系统空闲堆内存: %u 字节", (uint32_t)free_heap);
+    
     // 如果内存不足,增加延迟
-    osDelay(10);
+    // if (free_heap < 1024) {
+    //     WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "WebSocket: 系统内存不足,增加延迟");
+    //     osDelay(50);
+    // } else {
+        osDelay(10);
+    // }
 }
 
 /**
@@ -504,34 +411,17 @@ static void check_memory_status(void)
  */
 static void print_test_results(void)
 {
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "=== WebSocket多线程测试结果 ===");
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "活跃线程数: %u", active_thread_count);
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总发送数据包数: %u", total_send_count);
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总接收数据包数: %u", total_recv_count);
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总丢失数据包数: %u", total_lost_count);
-    
-    // 打印每个线程的统计信息
-    for (uint32_t i = 0; i < active_thread_count; i++) {
-        test_thread_info_t *thread_info = &test_threads[i];
-        if (thread_info->active) {
-            WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送=%u, 接收=%u, 丢失=%u", 
-                         i, thread_info->send_count, thread_info->recv_count, thread_info->lost_count);
-        }
-    }
-    
-    if (total_send_count > 0) {
-        float loss_rate = (float)total_lost_count / total_send_count * 100.0f;
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总丢包率: %.2f%%", loss_rate);
-    }
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "=== WebSocket测试结果 ===");
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送数据包数: %u", send_count);
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收数据包数: %u", recv_count);
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "丢失数据包数: %u", lost_count);
     
-    // 计算测试持续时间
-    if (test_start_time > 0) {
-        uint32_t test_end_time = osKernelGetTickCount();
-        uint32_t actual_duration = test_end_time - test_start_time;
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "实际测试持续时间: %u ms", actual_duration);
+    if (send_count > 0) {
+        float loss_rate = (float)lost_count / send_count * 100.0f;
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "丢包率: %.2f%%", loss_rate);
     }
     
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "================================");
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "========================");
 }
 
 /**
@@ -543,67 +433,66 @@ int at_test_websocket_handler(const char *cmd, const char *params)
         return -1;
     }
     
-    // 解析参数: AT^TESTWEBSOCKET=<server_addr>,<port>,<thread_count>[,<duration_ms>]
+    // 解析参数: AT^TESTWEBSOCKET=<server_addr>,<port1>
     char server_addr[64] = {0};
-    uint16_t port = 0;
-    uint32_t thread_count = 1;
-    uint32_t duration_ms = 0;
+    uint16_t port1 = 0, port2 = 0;
     
-    int parsed = sscanf(params, "%63[^,],%hu,%u,%u", server_addr, &port, &thread_count, &duration_ms);
-    if (parsed < 3) {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "参数格式错误,正确格式: AT^TESTWEBSOCKET=<server_addr>,<port>,<thread_count>[,<duration_ms>]");
+    if (sscanf(params, "%63[^,],%hu", server_addr, &port1) != 2) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "参数格式错误,正确格式: AT^TESTWEBSOCKET=<server_addr>,<port1>");
         return -1;
     }
     
-    // 设置默认值
-    if (thread_count == 0) thread_count = 1;
-    if (thread_count > MAX_CONCURRENT_THREADS) {
-        thread_count = MAX_CONCURRENT_THREADS;
-        WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "线程数超过最大限制,调整为: %u", thread_count);
-    }
-    
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "开始WebSocket多线程测试");
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "开始WebSocket测试");
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "服务器地址: %s", server_addr);
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "端口: %u", port);
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程数: %u", thread_count);
-    if (duration_ms > 0) {
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试持续时间: %u ms", duration_ms);
-    }
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "端口1: %u", port1);
     
     // 检查当前状态
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "当前测试状态: %d", test_state);
     if (test_state != TEST_STATE_IDLE) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试正在进行中,强制清理并重新开始");
-        cleanup_websocket_test();
-        total_send_count = 0;
-        total_recv_count = 0;
-        total_lost_count = 0;
+        // 强制清理
+        test_running = false;
+        if (test_client) {
+            lwip_close_websocket_client(test_client);
+            test_client = NULL;
+        }
+        test_state = TEST_STATE_IDLE;
+        send_count = 0;
+        recv_count = 0;
+        lost_count = 0;
     }
     
     // 初始化测试
-    if (!init_websocket_test(server_addr, port, thread_count, duration_ms)) {
+    if (!init_websocket_test(server_addr, port1)) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket测试初始化失败");
         return -1;
     }
     
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket多线程测试已启动,使用AT^STOPWEBSOCKET停止测试");
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试已启动,使用AT^STOPWEBSOCKET停止测试");
     return 0;
 }
 
 /**
  * 手动启动WebSocket测试
  */
-int start_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms)
+int start_websocket_test(const char *server_addr, uint16_t port, uint32_t duration_ms)
 {
     if (test_state != TEST_STATE_IDLE) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试正在进行中");
         return -1;
     }
     
-    if (!init_websocket_test(server_addr, port, thread_count, duration_ms)) {
+    if (!init_websocket_test(server_addr, port)) {
         return -1;
     }
     
+    // 如果指定了持续时间,则运行指定时间后自动停止
+    if (duration_ms > 0) {
+        osDelay(duration_ms);
+        cleanup_websocket_test();
+        print_test_results();
+    }
+    
     return 0;
 }
 
@@ -634,27 +523,9 @@ int get_websocket_test_state(void)
  */
 void get_websocket_test_stats(uint32_t *send_count_out, uint32_t *recv_count_out, uint32_t *lost_count_out)
 {
-    if (send_count_out) *send_count_out = total_send_count;
-    if (recv_count_out) *recv_count_out = total_recv_count;
-    if (lost_count_out) *lost_count_out = total_lost_count;
-}
-
-/**
- * 获取线程统计信息
- */
-void get_websocket_thread_stats(uint32_t thread_index, uint32_t *send_count_out, uint32_t *recv_count_out, uint32_t *lost_count_out)
-{
-    if (thread_index >= active_thread_count) {
-        if (send_count_out) *send_count_out = 0;
-        if (recv_count_out) *recv_count_out = 0;
-        if (lost_count_out) *lost_count_out = 0;
-        return;
-    }
-    
-    test_thread_info_t *thread_info = &test_threads[thread_index];
-    if (send_count_out) *send_count_out = thread_info->send_count;
-    if (recv_count_out) *recv_count_out = thread_info->recv_count;
-    if (lost_count_out) *lost_count_out = thread_info->lost_count;
+    if (send_count_out) *send_count_out = send_count;
+    if (recv_count_out) *recv_count_out = recv_count;
+    if (lost_count_out) *lost_count_out = lost_count;
 }
 
 /**
@@ -662,7 +533,7 @@ void get_websocket_thread_stats(uint32_t thread_index, uint32_t *send_count_out,
  */
 void websocket_test_init(void)
 {
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket多线程测试模块初始化");
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试模块初始化");
     
     // 注册AT命令处理器
     // 注意:这里需要根据实际的AT命令系统进行适配
index 20a89cf..34eaff8 100644 (file)
@@ -33,7 +33,7 @@ int at_test_websocket_handler(const char *cmd, const char *params);
  * @param duration_ms 测试持续时间(毫秒)
  * @return 0表示成功,-1表示失败
  */
-int start_websocket_test(const char *server_addr, uint16_t port, uint32_t duration_ms);
+int start_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms);
 
 /**
  * 停止WebSocket测试