STM32 LWIP netconn_write в цикле

Я взял проект LwIP_HTTP_Server_Netconn_RTOS (STM32CubeMX) и изменил код TCP-сервера, чтобы он был показан здесь. Но на стороне клиента я получаю такой результат:

S: SET / Num: 1 Num: 6 Num: 6 Num: 6 Num: 6 Num: 7 Num: 7

Что я делаю неправильно?

void http_server_serve(struct netconn *conn)
{
struct netbuf *inbuf;
char* buf;
u16_t buflen;
size_t len;
unsigned int call_times = 0;

#define SIZE_ARRAY 21
char data[SIZE_ARRAY]={0};

while(netconn_recv(conn, &inbuf) == ERR_OK)
{
    netbuf_data(inbuf, (void**)&buf, &buflen);

    if ((buflen >=5) && (strncmp(buf, "SET /", 5) == 0))
    {
        for(int i=0;i<7;i++)
        {
            if(conn->state == NETCONN_NONE)
            {
                sprintf(data, " Num: %d\n", ++call_times);
                len = strlen(data);
                printf(" Num: %d\n", call_times);
                netconn_write(conn, (const unsigned char*)(data), (size_t)len, NETCONN_NOFLAG);
            }
        }
        netbuf_delete(inbuf);
    }
}

netconn_close(conn);
netbuf_delete(inbuf);
}

person Eugene    schedule 29.12.2016    source источник


Ответы (1)


См. Эту неофициальную вики-страницу lwIP о netconn_write():

http://lwip.wikia.com/wiki/Netconn_write

err_t netconn_write ( struct netconn * aNetConn, const void * aData, size_t aSize, u8_t aApiFlags );

[...]

aApiFlags: любой из

  • NETCONN_NOCOPY, если данные стабильны на время передачи (статические данные или куча)
  • NETCONN_COPY, если данные нестабильны на время передачи (стек)

Тогда ваша первая ошибка - передать NETCONN_NOFLAG, что недопустимо. Скорее всего, NETCONN_NOFLAG численно равно NETCONN_NOCOPY. В этом случае lwIP будет отправлять данные прямо из вашего буфера, но это будет происходить «в фоновом режиме». Когда netconn_write(..., NETCONN_NOCOPY) возвращается, вы не должны НЕ изменять переданный буфер, пока передача не будет завершена. Поскольку вы изменяете его во время текущей передачи, вы получаете неверные результаты на принимающей стороне.

В вашем случае было бы довольно сложно получить информацию о том, что передача завершена - это можно сделать только с помощью обратного вызова. Даже если вы это сделаете, это не принесет вам никакой пользы, так как вам все равно придется просто дождаться события «передача завершена». Поэтому лучший вариант - просто использовать NETCONN_COPY.

person Freddie Chopin    schedule 30.12.2016