Не удалось отправить данные на сервер libwebsocket

Я пытаюсь написать небольшой плагин для X-Plane, чтобы создать простой сервер веб-сокетов с libwebsocket. Я могу подключиться к веб-сокету из Google Chrome, однако, когда я отправляю данные на сервер, X-Plane сразу падает.

Я почти уверен, что следующий код вызывает проблему:

unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + 13 + LWS_SEND_BUFFER_POST_PADDING);
buf = (unsigned char*) "Hello World!";
libwebsocket_write(wsi, buf, len, LWS_WRITE_TEXT);
free(buf);

Я вообще не программист/специалист на C, но есть ли у вышеизложенного вообще проблема?

Я разместил полный исходный код на Gist: https://gist.github.com/josefvanniekerk/868432986f2f963a5583


person josef.van.niekerk    schedule 03.02.2015    source источник


Ответы (2)


С любым разумным интерфейсом @iharob был бы прав - чтобы было ясно, что он / она права в том, что вы неправильно понимаете назначение строк.

Однако libwebsockets немного «особенный». Вам нужно скопировать строку в malloc() массив LWS_SEND_BUFFER_PRE_PADDING байтов. libwebsockets затем перезапишет предыдущие байты.

Итак, вы хотите что-то вроде (при условии, что вы не пытаетесь отправить завершающий ноль в строке):

char *text = "Hello World!";
int len = strlen (text);
unsigned char *buf = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
/* copy string but not terminating NUL */
memcpy (buf + LWS_SEND_BUFFER_PRE_PADDING, text, len );
libwebsocket_write(wsi, buf + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
free(buf);

Если вы хотите также отправить NUL:

char *text = "Hello World!";
int len = strlen (text) + 1;
unsigned char *buf = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
/* copy string including terminating NUL */
memcpy (buf + LWS_SEND_BUFFER_PRE_PADDING, text, len );
libwebsocket_write(wsi, buf + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
free(buf);
person abligh    schedule 03.02.2015
comment
Отлично, я вставил ваш код, и он работал на 100% из коробки. Большое спасибо @iharob - person josef.van.niekerk; 04.02.2015
comment
О, и насчет непонимания присваивания строк, здесь вы правы на 100%, я не опытный C-разработчик, я избалован другими языками, такими как PHP и JS. - person josef.van.niekerk; 04.02.2015

Вам нужно скопировать строку, назначение не работает, как вы ожидаете.

Вместо

buf = (unsigned char *)"Hello World";

тебе нужно

memcpy(buf, "Hello World", 1 + strlen("Hello World"));

когда вы выполняете присваивание, вы указываете buf на статический строковый литерал, а free() в этом случае невозможен.

Из-за этого ваша программа вызывает неопределенное поведение.

Вам нужно включить <string.h>

person Iharob Al Asimi    schedule 03.02.2015
comment
Боюсь, вы не совсем правы @iharob. libwebsockets это странно. Вам нужно предоставить ему буфер, в котором он гарантированно может писать в prepadding. Смотрите мой ответ. - person abligh; 04.02.2015
comment
Это unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + 13 + LWS_SEND_BUFFER_POST_PADDING); buf = (unsigned char*) "Hello World!"; неправильно, неважно что! Но я вижу вашу точку зрения. - person Iharob Al Asimi; 04.02.2015
comment
По крайней мере, memcpy() больше не приводит к падению X-Plane, небольшой прогресс. Однако не получая правильных данных в браузере, теперь получая какой-то ответ от сервера веб-сокетов. Возможно, именно здесь появляется особая часть libwebsocket. - person josef.van.niekerk; 04.02.2015
comment
Да. В своем ответе я ясно дал понять, что то, что вы написали, является правильным назначением строки, но не совсем преодолевает странность libwebsockets. С другой стороны, libwebsockets действительно работают... - person abligh; 04.02.2015