使用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
相关产品推荐
相关产品推荐

