【问题标题】:Libwesockets.h: Issue with lws_write: C++ string to C conversion and sendLibwesockets.h:lws_write 问题:C++ 字符串到 C 的转换并发送
【发布时间】:2019-10-23 04:22:00
【问题描述】:

我正在使用 g++。

代码:

        std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        char *cstr = strdup(str.c_str());
        lwsl_notice("\n%s", cstr);
        return lws_write(wsi, (unsigned char*)cstr, strlen(cstr), LWS_WRITE_TEXT);

这也行不通:

        std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        return lws_write(wsi, (unsigned char*)str.c_str(), strlen(str.c_str()), LWS_WRITE_TEXT);

但这工作正常(运行多次没有错误):

        char cstr[96] = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        return lws_write(wsi, (unsigned char*)cstr, strlen(cstr), LWS_WRITE_TEXT);

也尝试使用malloc 创建字符串,但这也不起作用:

        std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        char *cstr = (char *)malloc((str.length() + 1) * sizeof(char));
        strcpy(cstr, str.c_str());
        lwsl_notice("\n%s", cstr);
        return lws_write(wsi, (unsigned char*)cstr, strlen(cstr), LWS_WRITE_TEXT);

我可以多次运行此代码,但最终出现此错误free(): invalid next size (fast) (发送数据后失败)

我还尝试了对 LWS_PRE 的几个实验,但是当我将它添加到字符串时,它会在消息的开头添加几个符号,例如:a":

当我在发送数据后尝试free(cstr) 时,它立即失败并出现double free or corruption (out) 错误。

lws 版本:1.7.1 操作系统:ubuntu x64

【问题讨论】:

    标签: c++ string memory-management libwebsockets


    【解决方案1】:

    根据文档https://libwebsockets.org/lws-api-doc-master/html/group__sending-data.html#gafd5fdd285a0e25ba7e3e1051deec1001

    重要通知!

    使用 websocket 协议发送时

    LWS_WRITE_TEXT、LWS_WRITE_BINARY、LWS_WRITE_CONTINUATION、 LWS_WRITE_PING,LWS_WRITE_PONG,

    或在 http/2 上发送,

    发送缓冲区必须在缓冲区之前具有有效的 LWS_PRE 字节 传递给 lws_write() 的指针。

    这意味着您必须为缓冲区分配额外的 LWS_PRE 字节,即

    std::string str(LWS_PRE, ' '); //Allocate LWS_PRE bytes
    str += "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}"
    return lws_write(wsi, (unsigned char*)&str[LWS_PRE], str.size(), LWS_WRITE_TEXT);
    

    使用 malloc

    char* createMessage() {
      std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
      char *cstr = (char *)malloc(LWS_PRE + (str.length() + 1) * sizeof(char));
      cstr += LWS_PRE;
      strcpy(cstr, str.c_str());
      lwsl_notice("\n%s", cstr);
      return cstr;
    }
    ...
    char* msg = createMessage();
    lws_write(wsi, 
              (unsigned char*)msg, 
              strlen(msg) /* add 1 if receiver expects the null character*/, 
              LWS_WRITE_TEXT);
    free(msg - LWS_PRE);
    

    【讨论】:

    • 可以用malloc重写吗?我想分别“打包”消息字符串和“发送”。如果我的想法正确,我们将容器大小 str + LWS_PRE 字符串化。我重写了std::string str = "dsadsdsadsadasdasdasfsagdaggdsgds"; char *cstr = (char *)malloc((str.length() + 1) * sizeof(char) + LWS_PRE); strcpy(cstr, str.c_str()); return cstr;,然后发送lws_write(pss->wsi, (unsigned char*)message, strlen(message), LWS_WRITE_TEXT),但这一切都行不通..
    • 嗯......我检查了但它没有发送任何东西。我也会尝试 malloc 版本。也许这行得通..
    • 哇.. malloc 版本看起来工作。我会做更多的测试..仍然不确定..为此花了 5 个小时... eh
    • 是的。 C++ 版本似乎不起作用,但你帮我解决了我的问题!!!
    【解决方案2】:

    使用 libwebsockets 发送 C++ 字符串的简单方法:

    std::string payload = "Some sample string.";
    
    // prepare payload with lws header
    str buffer(LWS_SEND_BUFFER_PRE_PADDING + payload.size() + LWS_SEND_BUFFER_POST_PADDING, ' ');
    buffer.insert(LWS_SEND_BUFFER_PRE_PADDING, payload);
    
    // send message
    lws_write(wsi, (unsigned char*) &buffer[LWS_SEND_BUFFER_PRE_PADDING], payload.size(), LWS_WRITE_TEXT);
    

    【讨论】:

      猜你喜欢
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 2018-09-02
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      相关资源
      最近更新 更多