You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用websocat向libwebsockets C服务器发命令时出现额外字符问题

问题:websocat发送命令到libwebsockets服务器出现额外字符

使用websocat向基于libwebsockets开发的C语言WebSocket服务器发送命令(如open)时,服务器端收到的内容带有额外字符(例如openWiTG8mQpA4myt1aTI=),导致无法正常处理命令。服务器代码如下:

#include <libwebsockets.h>
#include <string.h>
#include <stdio.h>

static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason,
                       void *user, void *in, size_t len) {
    switch (reason) {
        case LWS_CALLBACK_ESTABLISHED:
            printf("Connection established\n");
            break;
        case LWS_CALLBACK_RECEIVE:
            printf("Message received: %s\n", (char *)in);
            break;
        default:
            printf("Unhandled callback reason: %d\n", reason);
            break;
    }
    return 0;
}

static struct lws_protocols protocols[] = {
    { "ws", callback_ws, 0, 1024 },
    { NULL, NULL, 0, 0 } // Terminator
};

int main(void) {
    struct lws_context_creation_info info;
    memset(&info, 0, sizeof info);
    info.port = 8080;
    info.protocols = protocols;
    struct lws_context *context = lws_create_context(&info);

    if (context == NULL) {
        fprintf(stderr, "lws init failed\n");
        return -1;
    }

    printf("Starting server...\n");
    while (1) {
        lws_service(context, 1000); // 1000 ms = 1 second
    }

    lws_context_destroy(context);
    return 0;
}

原因分析

  • 额外字符是Base64编码后缀,根源是websocat默认采用二进制模式发送数据,当前服务器代码直接将二进制数据当作C字符串打印,未区分WebSocket的文本/二进制帧类型,也未按实际数据长度处理内容。
  • 二进制模式下,websocat可能会对数据进行Base64编码或添加额外帧标识,服务器收到的是二进制格式数据,直接以字符串输出会包含非文本字符或编码后缀。

解决方案

方案1:修改websocat发送模式(快速解决)

使用文本模式发送命令,添加-t参数强制发送WebSocket文本帧:

websocat -t ws://localhost:8080

此时服务器收到的就是纯文本命令,无额外字符。

方案2:修改服务器代码适配二进制帧(通用兼容)

如果需要同时支持文本和二进制帧,修改回调函数,按实际数据长度处理,并区分帧类型:

static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason,
                       void *user, void *in, size_t len) {
    switch (reason) {
        case LWS_CALLBACK_ESTABLISHED:
            printf("Connection established\n");
            break;
        case LWS_CALLBACK_RECEIVE:
            // 打印原始数据长度和十六进制值,便于排查
            printf("Received %zu bytes: ", len);
            for (size_t i = 0; i < len; i++) {
                printf("%02x ", ((unsigned char *)in)[i]);
            }
            printf("\n");

            // 处理文本帧:复制数据到带终止符的缓冲区后打印
            if (lws_frame_is_text(wsi)) {
                char text_buf[1025] = {0};
                memcpy(text_buf, in, len > 1024 ? 1024 : len);
                printf("Text message: %s\n", text_buf);
            }
            // 可添加二进制帧处理逻辑
            break;
        default:
            printf("Unhandled callback reason: %d\n", reason);
            break;
    }
    return 0;
}

同时,确保lws_protocols中的接收缓冲区大小(第4个参数)足够容纳预期的最大数据长度。

方案3:检查websocat参数

避免使用--base64参数,该参数会强制对发送数据进行Base64编码,导致服务器收到编码后的内容。

内容的提问来源于stack exchange,提问作者mnekkach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:05:16