lwip 堆栈 netconn api 保持连接“保持活动”

Posted

技术标签:

【中文标题】lwip 堆栈 netconn api 保持连接“保持活动”【英文标题】:lwip stack netconn api keep connection "keep-alive" 【发布时间】:2015-06-12 03:11:22 【问题描述】:

我目前正在使用 lwip 堆栈来实现 modbus 服务器,但“keep-alive”功能不起作用。有人可以看看我的问题吗?

代码:

static void prvweb_ParsehtmlRequest( struct netconn *pxNetCon )

struct netbuf *pxRxBuffer;
portCHAR *pcRxString;
unsigned portSHORT usLength;
static unsigned portLONG ulPageHits = 0;

    while(netconn_recv( pxNetCon, &pxRxBuffer) != ERR_OK)
    
        vTaskDelay( webSHORT_DELAY );
    
    if( pxRxBuffer != NULL )
    
        /* Where is the data? */
        netbuf_data( pxRxBuffer, ( void * ) &pcRxString, &usLength );

        if(( NULL != pcRxString               )
        && ( !strncmp( pcRxString, "GET", 3 ) ))
        
            /********************************* 
                    Generate HTML page 
            *********************************/

            /* Write out the dynamically generated page. */
            netconn_write( pxNetCon, cDynamicPage, (u16_t) strlen( cDynamicPage ), NETCONN_COPY );
        
        netbuf_delete( pxRxBuffer );
    

    netconn_close( pxNetCon );
    netconn_delete( pxNetCon );

我更改了以下设置:

#ifndef LWIP_TCP_KEEPALIVE
#define LWIP_TCP_KEEPALIVE              1
#endif



#ifndef  TCP_KEEPIDLE_DEFAULT
#define  TCP_KEEPIDLE_DEFAULT     7200000UL /* Default KEEPALIVE timer in milliseconds */
#endif

#ifndef  TCP_KEEPINTVL_DEFAULT
#define  TCP_KEEPINTVL_DEFAULT    75000UL   /* Default Time between KEEPALIVE probes in milliseconds */
#endif

#ifndef  TCP_KEEPCNT_DEFAULT
#define  TCP_KEEPCNT_DEFAULT      9U        /* Default Counter for KEEPALIVE probes */
#endif

我的代码中还有其他必须做的事情吗?如果我尝试这样做,服务器将在传输 HTML 页面后结束连接。我试图删除 netconn_close( pxNetCon );和/或 netconn_delete(pxNetCon); ,但这不会给出正确的解决方案。连接将保持打开状态,但我无法再次连接。

还有其他我没有使用的设置吗?还是需要对代码进行修改?

【问题讨论】:

keep-alives 是指HTTP persistent connections? 嗨,不,我的意思是 TCP 协议的保持活动功能。该示例是一个 http 协议,但我正在尝试实现一个具有 keep-alive 功能的 modbus 服务器。 【参考方案1】:

如何在 Raw API 时启用 Keep-Alive

    在 lwipopts.h 中
#define LWIP_TCP_KEEPALIVE  1 // enable "kepp-alive"
#define TCP_KEEPIDLE_DEFAULT    1000 // keep_idle : dont' send keep-alive until keep_idle after connecting
#define TCP_KEEPCNT_DEFAULT     9U // keep_cnt : increase when no response after sending keep-alive every keep_intvl
    调用 tcp_connect(pcb, ...) 时
pcb->keep_intvl = 1000; // send "keep-alive" every 1000ms
    在循环中()...
if(pcb_client->keep_cnt==pcb_client->keep_cnt_sent)

    tcp_client_connection_close(pcb_client, client_s);

此设置使服务器拔出后超时 10 秒

【讨论】:

【参考方案2】:

LWIP_TCP_KEEPALIVE 控制编译以支持 TCP keepalives,默认情况下每个连接都关闭 keepalives。

上面的应用程序使用 netconn API 来管理它的连接,并且没有 netconn API 来启用 SO_KEEPALIVE 选项。为此,您需要使用 LwIP 的类似 BSD 的套接字 API 和 setsockopt() 调用:

int optval = 1; setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));

【讨论】:

您好,感谢您的回复!这解释了很多!在那种情况下,我将使用类似 BSD 的套接字 API!非常感谢! 嗨,我正在考虑,我有一个问题。 BSD 套接字 API 是建立在 Netconn api 之上的,那么 BSD 套接字怎么可能具有此功能而 Netconn API 却没有。使用它的原始 api 到这个? sockets API 执行的一些操作直接在低于 netconn 级别的 PCB(协议控制块)上进行操作。如果您查看第 2080 行附近的 sockets.c,我们可以看到 SO_KEEPALIVE 最终调用 ip_set_option() 来启用保活选项

以上是关于lwip 堆栈 netconn api 保持连接“保持活动”的主要内容,如果未能解决你的问题,请参考以下文章

lwip的内存管理

STM32 + LWIP - Pbuf 配置

当我尝试连接到服务器时,LWIP 中的路由错误

Keepalive服务器端?

如何使用 lwIP 堆栈发送简单的 HTTP 请求?

如何在 tls 中使用 STM32 lwip/mqtt api?