当调用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
}