C语言 LWIP + RTOS - 如何避免netconn永远阻塞线程



当调用LwIP netconn_accept()netconn_recv()函数时,如果我们使用的是RTOS,它将阻塞线程并等待连接直到超时或永远,具体取决于LWIP_SO_RCVTIME0的设置。超时持续时间等于SYS_ARCH_TIMEOUT

SYS_ARCH_TIMEOUT被定义为核心包含 LwIP 堆栈的一部分中的0xffffffff,因此我认为预计不会更改。

实际上,我希望它检查是否建立了连接,如果没有,则继续线程。但是,如果我调用netconn_accept(),它只会阻塞线程并永远(或很长时间)在那里等待......我不想只是更改SYS_ARCH_TIMEOUT的定义值,因为我在不同情况下需要不同的超时......

这样做

的好方法是什么?谢谢。

轮询 TCP 连接(或接受)通常是一种不好的做法。考虑生成一个专门用于阻塞 netconn_accept() 调用的新线程。

我理解使用 RTOS 的局限性,但仅生成一个具有最小堆栈空间的辅助线程应该不是一个主要问题。

我相信,实施经典生产者-消费者问题的解决方案并不难。

如果您谈论的是 FreeRTOS,它拥有所需的所有工具 - 信号量和线程。

根本不要使用阻塞 API。lwIP 堆栈提供本机、非阻塞、事件驱动的 API,它比阻塞更有效,并且不需要阻塞 RTOS。YouTube视频显示(http://youtu.be/MBk5wJ_8jEc)展示了如何在基于QP状态机框架的实时系统中使用此API。

创建一个新线程来尝试建立该连接。只要它没有连接,就让线程进入睡眠状态一段时间,以便 RTOS 可以进行上下文切换!(切换到另一个任务)

您可以使用

netconn_set_recvtimeout 函数将侦听套接字上的超时设置为小值,例如 1ms。

例如。(错误处理留新,绑定,侦听简单)

struct netconn *conn = netconn_new(NETCONN_TCP);
if (conn)
{
    if (netconn_bind(conn, IP_ADDR_ANY, 1025/*PORT_NUMBER*/) != ERR_OK)
    {
        return;
    }
    if (netconn_listen(conn) != ERR_OK)
    {
        return;
    }
    netconn_set_recvtimeout(conn, 1);
}

然后,接受的调用将最多延迟 1 毫秒:

struct netconn *newConn;
err_t result = netconn_accept(conn, &newConn);
if (result == ERR_OK)
{
    // Handle the connected netconn here
}
else if (result == ERR_TIMEOUT)
{
    // No pending connections
}
else
{
    // A problem with the listen socket accepting the connection
}

相关内容

  • 没有找到相关文章

最新更新