OBS:我正在使用STM32F2微控制器,FreeRTOS和lwIP,并且正在使用原始API
我有一个应用程序,可以在其中监听一台PC并连接到另一台PC。基本上,当我尝试实现高吞吐量时,所有功能都可以正常工作一段时间,但是大约半小时后...收到大约80〜90k数据包后会挂起。实际上它的挂起位置略有变化,但是当tcp_write返回err_mem时,当我开始关闭连接时,它就停止了执行。
有时它会挂在这行:
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:translationZ="2dp"
android:fitsSystemWindows="true"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Some other layouts -->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
有时,当我调用tcp_write时,它返回ERR_MEM,并且除了ERR_MEM之后,它什么也没有返回。这是我发送数据的方式,基本上我接受连接,接收数据,存储PCB,做点什么然后回复相同的PCB:
/* useg should point to last segment on unacked queue */
useg = pcb->unacked;
if (useg != NULL) {
for (; useg->next != NULL; useg = useg->next); <------- here
}
这是我设置监听套接字的方法:
err_t ret;
ret = tcp_write(g_response[i].pcb, data, len, 1);
if(ret == ERR_OK)
tcp_output(g_response[i].pcb);
else
tcp_close(g_response[i].pcb);
这是我对send和rcv的回调
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, port);
pcb = tcp_listen(pcb);
pcb->so_options |= SOF_KEEPALIVE; // enable keep-alive
pcb->keep_intvl = 1000; // sends keep-alive every second
tcp_accept(pcb, accept);
在没有ERR_MEM的情况下我关闭pcb时发送数据的方式可能很奇怪,但是现在丢失的数据包更少了,实际上它使我能够交换多达90k的数据包,然后才随机失败。
我实际上需要高吞吐量,这就是为什么我要调用tcp_output而不是让tcpip_thread处理发送数据包的原因。每当我让此线程占用数据包传输的时间时,它就可以工作,但是它太慢了(也许每200〜300 ms一个数据包,通过在函数中调用tcp_output,我到达了将数据发送到10 ms以下的地步) ...我也没有传输大量数据,因此很有帮助。
最近我注意到tcpip_thread调用了输入函数,转到了ipv4_input,转到了memp_free并一直运行,但从未退出(我实际上正在运行一个新测试,所以稍后我将使用在冻结之前将调用栈调用到输入中)。
有人做了类似的事情吗?高吞吐量的小数据包突发?
编辑:如所承诺的,这是我的调用堆栈
位于cmsis_os.c的osMutexWait():681 0x800474c位于sys_arch_protect()的
sys_arch.c:400 0x80146a6 do_memp_free_pool()at memp.c:415 0x800dca2
memp.c:486上的memp_free()0x800dcf8 tcp.c:1.336上的tcp_seg_free()
tcp_in.c处的0x800fb0e tcp_receive():c:1.162 0x8011712 tcp_process()处
tcp_in.c:877 0x8011048 tcp_input()at tcp_in.c:367 0x8010692
在ip4.c处为ip4_input():670 0x800c688在ethernet.c处为ethernet_input():176
tcpip.c上的0x80142fe tcpip_thread():c 0x8006836
位于port.c的pxPortInitialiseStack():231 0x8004cd0
就像@Lundin所说的,这是一个并发问题。我可能应该尝试更小心地调用函数。我将尝试修改代码以使用netconn或socket而不是tcp_pcb,然后测量速度。我真的需要高吞吐量