当调用 LwIP netconn_accept()
或netconn_recv()
函数时,如果我们使用RTOS,它将阻塞线程并等待连接,直到超时或永远,取决于LWIP_SO_RCVTIME0
的设置。超时持续时间等于SYS_ARCH_TIMEOUT
。
SYS_ARCH_TIMEOUT
在LwIP堆栈的核心包含部分中定义为 0xffffffff ,因此我认为预计不会更改。
实际上,我希望它检查是否建立了连接,如果没有,则继续该线程。但是,如果我调用netconn_accept()
,它将阻止线程并在那里永远等待(或很长时间)......我不想jsut更改SYS_ARCH_TIMEOUT
的定义值,因为我在不同的情况下需要不同的超时...
这样做的好方法是什么?感谢。
答案 0 :(得分:6)
轮询TCP连接(或接受)通常是一种不好的做法。考虑生成一个专门用于阻塞netconn_accept()调用的新线程。
我理解使用RTOS的局限性,但只产生一个具有最小堆栈空间的辅助线程不应该是一个主要问题。
我认为实施经典Producer-Consumer problem的解决方案并不难。
如果您正在谈论FreeRTOS,它拥有所需的所有工具 - 信号量和线程。
答案 1 :(得分:5)
根本不要使用阻止API。 lwIP堆栈提供了一个本机的,非阻塞的,事件驱动的API,它比阻塞更有效,并且不需要阻塞RTOS。 YouTube视频显示(http://youtu.be/MBk5wJ_8jEc)显示了如何在基于QP状态机框架的实时系统中使用此API。
答案 2 :(得分:3)
创建一个新线程尝试建立该连接。只要它没有连接,就让线程进入休眠状态一段时间,这样RTOS就可以进行上下文切换! (切换到另一个任务)
答案 3 :(得分:1)
您可以使用netconn_set_recvtimeout
函数将侦听套接字上的超时设置为较小的值,例如1ms。
EG。 (错误处理留下新的,绑定,听取简单)
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);
}
然后接受的呼叫将延迟最长1ms:
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
}