1

I'm using g++.

Code:

        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);

This also doesn't work:

        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);

But this works fine (runs many times without some error):

        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);

Tried also to create string with malloc but this doesn't work as well:

        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);

I can run this code couple times but eventually I'm getting this error: free(): invalid next size (fast) (fails after data was sent)

I tried also couple experiments with LWS_PRE but when I add this to the string it adds couple symbols at the start of message like: a":

When I try free(cstr) after sending the data it fails immediately with double free or corruption (out) error.

lws version: 1.7.1 os: ubuntu x64

xercool
  • 883
  • 1
  • 8
  • 24

2 Answers2

2

According to documentation https://libwebsockets.org/lws-api-doc-master/html/group__sending-data.html#gafd5fdd285a0e25ba7e3e1051deec1001

IMPORTANT NOTICE!

When sending with websocket protocol

LWS_WRITE_TEXT, LWS_WRITE_BINARY, LWS_WRITE_CONTINUATION, LWS_WRITE_PING, LWS_WRITE_PONG,

or sending on http/2,

the send buffer has to have LWS_PRE bytes valid BEFORE the buffer pointer you pass to lws_write().

This means that you have to allocate extra LWS_PRE bytes for your buffer i.e

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);

Using 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);
Gerard097
  • 815
  • 4
  • 12
  • Is it possible to rewrite it with malloc? I'd like to keep "packing" message string and "sending" separately. If I got this idea right we string container size str + LWS_PRE. I rewrited ```std::string str = "dsadsdsadsadasdasdasfsagdaggdsgds"; char *cstr = (char *)malloc((str.length() + 1) * sizeof(char) + LWS_PRE); strcpy(cstr, str.c_str()); return cstr;``` and then send `lws_write(pss->wsi, (unsigned char*)message, strlen(message), LWS_WRITE_TEXT)` but this all doesn't work.. – xercool Oct 23 '19 at 05:36
  • Hmm ... I checked but it doesn't send anything. I'll try malloc version as well. Maybe that works.. – xercool Oct 23 '19 at 05:49
  • Wow.. malloc version looks working. I'll do more tests.. still not sure.. spent 5 hours for this... eh – xercool Oct 23 '19 at 05:52
  • Yep. C++ version doesn't seem working but THHHAANKS you helped me with my issue!!! – xercool Oct 23 '19 at 05:58
0

Simple way to send C++ strings with libwebsockets:

std::string payload = "Some sample string.";

// prepare payload with lws header
std::string buffer(LWS_SEND_BUFFER_PRE_PADDING + payload.size(), ' ');
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);
RobGo
  • 1
  • 1