реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> lwIp tcp клиент для STM32, как принять больше одного сообщения
realqwerty
сообщение May 31 2018, 05:55
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 12-11-10
Пользователь №: 60 830



имеется сервер TCP, который на запрос клиента "M\r" отправляет два сообщения:
1. "ОК\r"
2. "какое-то значение\r"

имеется отладка stm32f746g-disco и пример "LwIP_TCP_Echo_Client" из набора STM32Cube.

работает замечательно, за исключением одного, не принимает сообщение №2.
т.е. после приема первого сообщения соединение закрывается.

CODE

err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
struct echoclient *es;
err_t ret_err;

LWIP_ASSERT("arg != NULL", arg != NULL);

es = (struct echoclient *)arg;

/* if we receive an empty tcp frame from server => close connection */
if (p == NULL)
{
/* remote host closed connection */
es->state = ES_CLOSING;
if (es->p_tx == NULL)
{
/* we're done sending, close connection */
tcp_echoclient_connection_close(tpcb, es);
}
else
{
/* send remaining data*/
tcp_echoclient_send(tpcb, es);
}
ret_err = ERR_OK;
}
/* else : a non empty frame was received from echo server but for some reason err != ERR_OK */
else if (err != ERR_OK)
{
/* free received pbuf*/
if (p != NULL)
{
pbuf_free(p);
}
ret_err = err;
}
else if (es->state == ES_CONNECTED)
{
/* increment message count */
message_count++;

/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);

es->p_tx = p;
char strmr[20] = "";
strncpy(strmr, es->p_tx->payload, es->p_tx->len); // здесь считали сообщение
printf("%d %s\n", message_count, strmr);

pbuf_free(p);
tcp_echoclient_connection_close(tpcb, es); // соединение закрывается
ret_err = ERR_OK;
}

/* data received when connection already closed */
else
{
/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);
/* free pbuf and do nothing */
pbuf_free(p);
ret_err = ERR_OK;
}
return ret_err;
}


если соединение закрывать после второго сообщения,
CODE

else if(es->state == ES_CONNECTED)
{
/* increment message count */
message_count++;

/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);

es->p_tx = p;
char strmr[20] = "";
strncpy (strmr,es->p_tx->payload,es->p_tx->len);
//strmr[es->p_tx->len] = '\r';
printf ("%d %s\n", message_count, strmr);

if (strncmp(strmr, "OK", 2) == 0)
{
pbuf_free(p);
}
else
{
pbuf_free(p);
tcp_echoclient_connection_close(tpcb, es);
}
ret_err = ERR_OK;
}

то происходит переполнение буфера и ...
1 OK
2 4680235013820
3 OK
4 4680235013820
5 OK
6 4680235013820
7 OK
8 4680235013820
9 OK
10 4680235013820
11 OK
Assertion "pbuf_free: p->ref > 0" failed at line 747 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
Assertion "mem_free: legal memory" failed at line 430 in ../Middlewares/Third_Party/LwIP/src/core/mem.c
Assertion "pbuf_free: p->ref > 0" failed at line 747 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
Assertion "tcp_write: arg == NULL (programmer violates API)" failed at line 401 in ../Middlewares/Third_Party/LwIP/src/core/tcp_out.c
Assertion "tcp_write: arg == NULL (programmer violates API)" failed at line 401 in ../Middlewares/Third_Party/LwIP/src/core/tcp_out.c
12 ER
smile3046.gif


попробовал с компьютера в visual studio написать запрос

187 - запрос "M\r"
192 - ответ "OK\r"
198 - ответ "4680235013820"



подскажите пожалуйста как правильно организовать прием второго пакета

Сообщение отредактировал realqwerty - May 31 2018, 06:00
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение May 31 2018, 08:56
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 180
Регистрация: 16-10-15
Пользователь №: 88 894



Вроде-бы lwIp работает точно так-же как терминал - учитывает управляющий символ строки. Если конечно это не вырезано с корнем.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 31 2018, 09:04
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 975
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(AVI-crak @ May 31 2018, 11:56) *
Вроде-бы lwIp работает точно так-же как терминал - учитывает управляющий символ строки. Если конечно это не вырезано с корнем.

Это из рубрики "вредные советы". Lwip вообще не заглядывает в данные, когда речь идёт о голом TCP.
Go to the top of the page
 
+Quote Post
0men
сообщение May 31 2018, 10:15
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 76
Регистрация: 7-05-05
Пользователь №: 4 819



Нужно просто переписать эхоклиент из примера под свою задачу. Для этого нужно просто разобраться с основными функциями lwip и принципом его работы. Возьмите для начала в качестве сервера терминалку hercules

Сообщение отредактировал 0men - May 31 2018, 10:21
Go to the top of the page
 
+Quote Post
scifi
сообщение May 31 2018, 10:53
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 975
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(0men @ May 31 2018, 13:15) *
Нужно просто переписать эхоклиент из примера под свою задачу. Для этого нужно просто разобраться с основными функциями lwip и принципом его работы. Возьмите для начала в качестве сервера терминалку hercules

В своё время смотрел на это эхо в качестве примера. Слишком там замудрёно, особенно для новичка. Я бы советовал посмотреть на веб сервер, там есть пара полезных идей. Правда, код перегружен вот этой условной компиляцией, но куда деваться?
Go to the top of the page
 
+Quote Post
realqwerty
сообщение May 31 2018, 11:23
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 12-11-10
Пользователь №: 60 830



а на халяву не прокатит: "тут" поставить очистку буфера, а "тут" отключение соединения?

Сообщение отредактировал realqwerty - May 31 2018, 11:24
Go to the top of the page
 
+Quote Post
0men
сообщение May 31 2018, 11:29
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 76
Регистрация: 7-05-05
Пользователь №: 4 819



Цитата(scifi @ May 31 2018, 13:53) *
В своё время смотрел на это эхо в качестве примера. Слишком там замудрёно, особенно для новичка. Я бы советовал посмотреть на веб сервер, там есть пара полезных идей. Правда, код перегружен вот этой условной компиляцией, но куда деваться?


Да, там основная сложность в том, что данные для отправки задаются в виде связного списка и содержатся внутри спец структуры. Но, по идее, там все красиво сделано - отправили первый сегмент, залудили колл-бек функцию по приходу аска, смотрим есть ли еще данные, если есть отправляем и снова колбек, если нет, то освобождаем всю память и закрываем соединение. Но я у себя все переписал, не люблю связные списки ))

Сообщение отредактировал 0men - May 31 2018, 11:29
Go to the top of the page
 
+Quote Post
kolobok0
сообщение May 31 2018, 16:33
Сообщение #8


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 185
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(realqwerty @ May 31 2018, 08:55) *
имеется сервер...как правильно организовать прием второго пакета


для начала индуский говнокод привести к рабочему примеру. для этого не полениться и глазками посмотреть, головой подумать, ручками понажимать.
в процессе рихтования - большая вероятность, что сами и обнаружите ляпы...

удачи вам
(круглый)
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение May 31 2018, 16:34
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 180
Регистрация: 16-10-15
Пользователь №: 88 894



Цитата(scifi @ May 31 2018, 15:04) *
Это из рубрики "вредные советы".

Ну значит вырезано.
Подсчитывать байты в пользовательской функции - это как землю руками вращать.
Go to the top of the page
 
+Quote Post
realqwerty
сообщение Jun 1 2018, 02:12
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 12-11-10
Пользователь №: 60 830



сделал с использованием сокетов, получилось неожиданно легко, где будут грабли?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 14th August 2018 - 08:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.02398 секунд с 7
ELECTRONIX ©2004-2016