LwIP - netconn API - 当进程被阻塞时如何发送TCP数据包?

7
我正在使用FreeRTOS + LwIP开发基于以太网的床头护士呼叫设备。在阅读了一些示例和文档之后,我想使用LwIP的netconn API在TCP下发送和接收数据,因为我不熟悉BSD风格的API,而且原始API可能比较困难。
我知道netconn_accept()函数将会阻塞进程,直到远程主机发出连接请求,而netconn_recv()函数也会阻塞进程,同时等待数据到达...这两个函数都会阻塞进程,对于服务器接收数据来说是很好的,然而我的设备还需要作为客户端来触发一个“呼叫”到护士中心,当病人按下按钮时。那么,在等待远程主机连接(阻塞进程)的同时,它如何发起发送TCP数据包呢?
我需要发送TCP,因为我必须使用SIP(会话初始化协议)来发起呼叫,而且它应该是可靠的,因为这是一种医疗设备。非常感谢。

由于我正在使用FreeRTOS,今天我尝试使用两个线程,一个作为服务器等待连接,另一个作为客户端在需要时打开TCP连接。服务器线程运行良好,但在客户端方面,当我调用netconn_connect()时它总是返回错误...我尝试使用相同和不同的端口来设置服务器和客户端,但仍然失败了。 - eepty
请帮我解决这个问题,https://stackoverflow.com/questions/51112786/ethernet-unplugged-state-verification-by-netconn-api - Nitin Rawal
1个回答

7
您不能在远程主机初始化连接之前向其发送数据。这毫无意义。我的问题是:您是否希望您的设备连接到远程主机,还是希望远程主机发起与您的设备的连接?
现在,在您的设备中使用了netconn_accept - 这意味着您正在等待远程主机发起与您的设备的连接,然后您的设备才能向远程主机发出信号。这是您编写的代码的完全预期行为,但您似乎对此感到担忧。这不是您的意图吗?如果不是,为什么要这样编码?另一种选择是让您的设备启动与远程主机的连接。这里有一个使用netconns的示例here。当然,这也涉及对系统中其他设备的更改。
所以,这个故事的道德是,在没有连接的情况下,您不能发送任何数据,并且您正在等待连接才能发送数据。您不想等待连接,因此必须更改软件以启动连接,而不是等待另一方启动连接。
另一个可能遇到的问题是,您希望能够在同一连接上同时发送和接收数据。我看到的大多数lwip示例涉及阻塞调用等待数据,然后通过传输回应来对该数据做出反应。有时您想在先不接收任何东西的情况下立即传输回应。我也可以帮忙解决这个问题。
以下是我创建监听netconn连接时使用的方法:
首先,您必须通过设置以下内容启用超时:
#define LWIP_SO_RCVTIMEO 1
然后,您必须将netconn设置为类似于以下方式:

pxTCPListener = netconn_new (NETCONN_TCP);

netconn_bind (pxTCPListener, NULL, 23);

netconn_listen (pxTCPListener);

pxNewConnection = netconn_accept (pxTCPListener); //此处会阻塞,直到连接被接受

//这是重要的一行!

pxNewConnection->recv_timeout = 10; //注意这是毫秒 - lwip以毫秒为单位工作

//这个循环将持续到连接关闭

while(!ERR_IS_FATAL(pxNewConnection->err)) { //致命错误包括连接关闭、重置、中止等

//此netconn_recv调用现在将等待10ms以获取任何新数据,然后返回

if ((pxRxBuffer = netconn_recv (pxNewConnection)) != NULL) {

//处理接收到的数据

}

//在此处执行任何传输操作

} //上述while循环结束

该代码允许您同时进行传输和接收而不必担心阻塞。


谢谢Stephen,护士呼叫设备将作为服务器运行,等待连接。 - eepty
是啊,为什么呢?似乎呼叫设备应该启动与服务器的连接,因为触发所有操作的动作是某人按下按钮,而不是等待某些东西连接到它,以便它可以告诉它按下了一个按钮。 - Stephen Friederichs
非常感谢您详细的回答,Stephen。该设备类似于手机,通常等待连接,充当服务器,但如果有人按下它上面的按钮,它将发起连接,充当客户端。这两种情况不会同时存在,并且两种情况都涉及接收和传输。最近,我成功地分别实现了这两个任务...经过长时间的阅读...我在FreeRTOS中将它们分成了两个不同的任务,启用一个任务将阻塞另一个任务。我已经分别测试了每个任务,但尚未测试它们一起运行...我是RTOS的新手,但我会尝试。 - eepty
嗨,Stephen,你的代码行 "while(!ERR_IS_FATAL(pxNewConnection->err))" 对我帮助很大。虽然我之前能够接收和发送数据,但是每次接收数据都需要重新连接和断开TCP连接,否则程序会挂起。再次感谢你。 - eepty
是的,对我来说也是很好的一个例子。关于全双工通信的示例并不多。 - Stephen Friederichs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接