LWIP的大文件下載數據錯誤

前段時間在做stm32 web下載文件的功能,遇到了一個問題。使用不同的瀏覽器下載得到的文件數據有所差異。通過具體分析發現使用谷歌和迅雷下載得到的文件是正確的,而使用360,搜狗之類的瀏覽器得到的文件數據會丟失一個包的數據,而丟失的數據恰巧在瀏覽器彈出文件對話框選擇保存路徑的時候。

 

有了重現問題的方法就好辦,打開wireshark抓包工具,重新操作一遍下載過程,wireshark設置過濾

tcp and ip.addr == 192.168.1.228 and tcp.port==80

只抓取tcp的數據,找到瀏覽器打開文件選擇對話框前後的抓包顯示。

瀏覽器發送紅色箭頭的包之後彈出文件選擇對話框停止了。要了解wireshark顯示的抓包數據,我們先來溫習下tcp的過程。

 

三次握手

第一次

第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SENT狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。

 

第二次

第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(seq=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

 

第三次

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。

 

標誌控制

URG:緊急標誌

緊急(The urgent pointer) 標誌有效。緊急標誌置位,

ACK:確認標誌

確認編號(Acknowledgement Number)欄有效。大多數情況下該標誌

位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure:1)爲下一個預期的序列編號,同時提示遠端系統已經成功接收所有數據。

PSH:推標誌

該標誌置位時,接收端不將該數據進行隊列處理,而是儘可能快將數據轉由應用處理。在處理 telnet 或 rlogin 等交互模式的連接時,該標誌總是置位的。

RST:復位標誌

復位標誌有效。用於復位相應的TCP連接。

SYN:同步標誌

同步序列編號(Synchronize Sequence Numbers)欄有效。該標誌僅在三次握手建立TCP連接時有效。它提示TCP連接的服務端檢查序列編號,該序列編號爲TCP連接初始端(一般是客戶端)的初始序列編號。在這裏,可以把TCP序列編號看作是一個範圍從0到4,294,967,295的32位計數器。通過TCP連接交換的數據中每一個字節都經過序列編號。在TCP報頭中的序列編號欄包括了TCP分段中第一個字節的序列編號。

FIN:結束標誌

帶有該標誌置位的數據包用來結束一個TCP回話,但對應端口仍處於開放狀態,準備接收後續數據。

 

在LWIP中tcp_mss設置的是1460,http發送數據設置的是2*tcp_mss。而對比之前的數據瀏覽器發送一個ack,web服務器返回ack和一個psh,ack.  此時明顯少了一個psh,ack的數據包。

 

進一步來看這些信息

ack=seq+len, 沒毛病,這裏說明tcp的傳輸是沒有問題。  而另一個字段Win表示窗口大小,窗口表示的當前緩衝區還可以容納多少bytes的數據。在圖中Win=2755,明顯不夠容納2*tcp_mss=2920的數據 。這說明了tcp協議的底層處理是沒問題的(發多了發不出去) ,而是應用層問題。

 

 

找到http讀寫文件地方,發現讀指針並沒有判斷當前實際發送數據大小或接收窗大小。大家在做此類似應用的注意了。

 

如果想要了解更多知識,可以關注公衆號【DSP-Tech】.你也可以加我微信,和我一起共同成長學習吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章