多個客戶端連TCP_Server就有問題,lwIP的這個Bug,你一定要小心

怎麼去下載lwIP的源碼,怎麼去查看lwIP的buglist

這裡給出幾個lwIP官網的連結
  1. lwIP官網:http://savannah.nongnu.org/projects/lwip/
  2. lwIP的源碼下載地址:http://download.savannah.nongnu.org/releases/lwip/
  3. lwIP的buglist查看:http://savannah.nongnu.org/bugs/?group=lwip


TCP的長連接與短連接
通常來說TCP有長連接與短連接之分。
長連接與短連接的區別在於:
長連接在連接建立以後,可以進行多次數據交互,通信完成以後再斷開連接,因為連接持續的時間比較長,所以叫長連接。
短連接是每進行一次數據交互都要按照建立連接 -》數據交互-》斷開連接的 流程進行。因為每一次連接持續的時間比較短,所以叫短連接。

lwIP協議在處理短連接時候的bug
通常來說我們用的TCP 客戶端都是基於長連接的,也就是說一旦連接建立以後,就基於這條連接上進行數據交互。比如說我們常用的網絡調試助手,但是也會有基於TCP短連接,Client是長連接還是短連接,取決於客戶需求。但是使用lwIP RAW搭建TCP Server的時候,要注意lwIP本身的一個bug,可能會造成基於短連接的客戶端連接問題。
·         問題描述:
TCP伺服器搭建完成以後,發現使用TCP客戶端連接以後,剛開始數據交互正常,但是一段時間以後,就無法發送了。
·         問題測試:
通過wireshark抓包發現,在TCP每一次發送數據之前都會重新連接,數據發送完成以後都會斷開連接,所以這個TCP客戶端是基於短連接的客戶端。
·         問題分析:
wireshark再次抓包發現,TCP客戶端已經發出了握手的SYN數據包,但Server沒有任何的反饋 。於是打開lwIP TCP調試選項發現在tcp_listen_input :

#if TCP_LISTEN_BACKLOG if (pcb->accepts_pending >= pcb->backlog)
{
LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
return ERR_ABRT;
}
#endif /* TCP_LISTEN_BACKLOG */

這裡報錯,所以確定是backlog數量太小。但是把backlog擴大,依然會有問題。原因在於accepts_pending並沒有釋放。按理說 tcp listen函數中的 backlog只是限定監聽狀態下的連接數量,也就是還沒有完成完成三次握手,或者已經完成三次握手但是還沒有被accept的連接數量 ,但是在實際測試過程中發現,當實際連接到TCP伺服器的客戶端數量超過 TCP_DEFAULT_LISTEN_BACKLOG 的時候,會有客戶端連接不了伺服器的原因。
於是上網查了下發現lwIP官網上已經有說到這個bug並且還給出了patchpatch 打上以後,啥都好了。

最後附上lwip 官網上給定的bug 的描述與解決方法 :
http://savannah.nongnu.org/bugs/?46696


留言

這個網誌中的熱門文章

python serial 模組使用方法 #1

USB HID 教學 #1(轉載)

USB HID 教學 #2 (轉載)