話說這個是真難找啊。我僅僅發表我找到的問題。
我在接收幾十到幾百次數據的時候,會出現連接超時,也就是time out。而且ping也ping不通。也就是說明lwip出了問題。
首先我先介紹modbus的這個流程。
首先是函數
eMBTCPInit( MB_TCP_PORT_USE_DEFAULT )
我們進入看看做了什么。主要函數為:
eMBTCPDoInit( ucTCPPort )||vxMBTCPPortInit( ucTCPPort )||v
tcp_new()---->tcp_bind()---->tcp_listen()---->tcp_accept()
重點在于這個函數,這里設置了回調。我們看看這個設置的回調函數:
tcp_accept( pxPCBListenNew, prvxMBTCPPortAccept );這里的prvxMBTCPPortAccept ||調用了vtcp_recv( pxPCB, prvxMBTCPPortReceive );
我們看看tcp_recv,發現其主要是設置了接受回調函數,當收到數據后,調用接受函數來處理tcp幀。
進入這個函數看看
err_t
prvxMBTCPPortReceive( void *pvArg, struct tcp_pcb *pxPCB, struct pbuf *p, err_t xErr )||v
tcp_recved( pxPCB, p->len );這個內部調用了一個接收函數。||進入這個tcp_recved函數vif (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {tcp_ack_now(pcb);tcp_output(pcb);
}
我們發現這里,三行的意思是:
????????如果之前你通告的窗口很小甚至 0(對端幾乎/完全停發),你現在一下子釋放了不少空間,就馬上通知對端“可以繼續沖了”,避免對端等到延遲 ACK 定時器或其他機會才知道 → 降低停頓時延。
????????同時不對每個很小的釋放都即時發 ACK(那樣 ACK 會太多),所以設置閾值來折中ACK 數量和時延。
也就是說,只有你一次性釋放 ≥ 730 字節(我這里是這么大)窗口時才會立刻發 ACK。
????????大家可以仿真到這里,打上斷點,看看能不能進入這個判斷中。如果都出現報錯了還是進不去,就說明這個設置太大了。你應該設置的小點,或者刪去判斷,一幀一個ack。?????
???????????