關於TCP或FTP異常斷開的處理方法總結


  最近在項目中遇到一些小小的問題,犯過的錯希望不要犯二次。我Linux環境下開啟一個TCP服務和FTP客戶端用來升級系統,正常情況下是沒任何差錯的,如果斷網(拔網線)或者PC端升級軟件(QT軟件)崩潰(強行退出),系統就會出現問題,

  流程有2個,一個是FTP下載過程,一個是Flash寫入過程,都涉及進度值的上傳,即無時無刻都在調用write函數,並且進度函數的返回值是不處理的,也是沒有任何函數來處理檢測此函數是否正常運行的,主要是沒法處理接收。

  FTP下載CURL設置: 進度函數部分

 

  TCP在正常網絡下是“三次握手,四次揮手”,服務器和客戶機分別正常退出處理是沒什么問題的。

   一、如果突然斷網了,PC端TCP客戶機不會發任何信息,可能出現的問題有:

    ①此時如果還處於TCP命令交互過程,可添加keepalive機制(只開啟設置當前套接字的keepalive屬性),保證規定時間內沒有回響可關閉套接字,等待下一次連接。注意不能更改Linux整個系統的keepalive值

       系統keepalive值可通過sysctl -a 或者 sysctl -a  |grep tcp_keepalive*   查看

      

      當前tcp套接字keepalive設置代碼:

    

 

    ②此時如果處於FTP下載過程中,curl庫會一直卡死在那里,無法自動退出來(curl設計機制問題,沒法更改),但是進度函數里面write不會報錯(斷網情況下返回值不為-1),導致此更新進程模塊廢掉,只能重啟,解決辦法可以添加curl下載超時限制CURLOPT_TIMEOUT,該延時表示多久到了文件還沒有下載完成curl就會自動斷開重新連接下載,由於斷網,此時連接超時(CURLOPT_CONNECTTIMEOUT)將會自動退出,從而可以正常處理,程序如下

    curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 120);

此語句缺點就是不管多大文件,只給你120S的下載時間,如果文件過大,120S下載不完,那么一直死循環下載會出問題,所以不到萬不得已不要使用,由於項目實際文件最大的才6M多點,一般正常網絡情況下30s內可解決戰斗,遇到網絡不好的可能時間長點,

此延時時間設置太大也不行,沒有及時性,都出問題了,你不可能讓客戶等很長時間吧?客戶還以為更新失敗成磚了,直接報廢處理了。

    ③此時處於寫入過程中時。進度函數中write也不會出錯,也沒法接收,就讓它寫完再在FTP連接的過程中失敗退出吧。

 

         二、若果上位機突然崩潰了,此時window 系統會回收套接字,給tcp服務器端發送一個RST信號,此時Linux下面處於集中情況:

  ①此時如果還處於TCP命令交互過程中,與上一樣,有keepalive機制,規定時間內可以自動斷開,等待下一次連接。

  ②此時如果處於FTP下載過程中,由於進度函數不斷被調用,不斷循環(curl設置1S時間調用進度函數一次)調用write函數上發數據,上面崩潰時也會不斷被調用,第一次調用write會返回-1,第二次再調用write就會阻塞卡死在write這里(這個地方吃了大虧),不得不吐槽curl庫,既然FTP服務器端都沒了,出問題了,客戶端怎么還是不停的調用進度函數?上面提到了curl中是不涉及處理進度函數返回值的,管你是不是出錯,這時候沒辦法啊,既然出錯了,我的要趕緊退到初始調用FTP下載到的地方吧?怎么辦?在函數之間進行跳轉的恐怕只有setjmp()  / longjmp()吧?C語言錯誤異常跳轉特殊函數,與函數AR地址相關的,比goto還厲害的語句。

在最最開始頂層的地方設置如下: 

AbnormalFlag = setjmp(Ftpdown_jb);
if(AbnormalFlag == 0 )
{
/* null */
}
else if(AbnormalFlag == 1 )
{
 Enter setjmp Ftpdown_jb abnormar  
FileSuccessAllFlag = 0;
goto end;
}
else
{
/* null */
}

ret = FtpDownload(***);

 

然后在進度函數中write中寫入如下

ret = write(G_sock_c,SendBuff,ret);
if(ret < 0)
{
     **** 
   longjmp(Ftpdown_jb,1);
}

write第一次出錯,保證能退出來,實現函數隔層之間的的跳轉,然后釋放當前套接字,等待下一次連接。

  ③此時處於flash過程與上同理處理。

好了,寫了這么多,有不嚴謹之處還請指教。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM