項目開發過程中遇到的問題

問題分類:
1、邏輯問題:結構、處理流程的設計有問題,尤其在多線程操作同一個對象時;
2、接口定義和使用問題:例如接口結構或返回情況改了,未及時編譯或更改其他模塊的調用;
3、對接問題:對講問題不是你的問題,就是我的問題,需要聯查;
4、理解問題:對功能、邏輯流程或函數定義和使用的理解不清晰;
5、異常處理機制問題;
6、代碼細節問題:變量類型、返回值、引用、指針;

socket綁定(bind)本地端口失敗

問題描述:地標協議在啓用時,會主動向平臺註冊,socket本地端口6600(可修改),當快速關閉使能再打開時,概率性出現socket綁定本地端口失敗。

問題分析:bind 普遍遭遇的問題是試圖綁定一個已經在使用的端口。 該陷阱是也許沒有活動的套接字存在,但仍然禁止綁定端口(bind 返回 EADDRINUSE),它由 TCP 套接字狀態 TIME_WAIT 引起。該狀態在套接字關閉後約保留 2 到 4 分鐘。在 TIME_WAIT 狀態退出之後,套接字被刪除,該地址才能被重新綁定而不出問題。

解決方法:等待 TIME_WAIT 結束可能是令人惱火的一件事,特別是如果您正在開發一個套接字服務器,就需要停止服務器來做一些改動,然後重啓。幸運的是,有方法可以避開 TIME_WAIT 狀態。可以給套接字應用 SO_REUSEADDR 套接字選項,以便端口可以馬上重用。通過sesockopt函數重置本地端口來解決該問題;

線程池、任務隊列阻塞問題

問題描述:有遠程操控協議爲TCP短連接,通過客戶端操作設備時,設備會頻繁的創建線程、銷燬線程,後來將設備端來請求就創建線程的機制,修改爲線程池模式(固定創建4個線程,來處理請求)。線程池模型機制如下:

epoll監聽socket狀態
 → 設備/服務端檢測socket可讀 
 	→ 創建task丟進任務隊列 
 		→  若任務隊列爲空則喚醒一個等待線程(線程池線程通過條件變量阻塞)

邏輯上是來一個任務,即喚醒一個阻塞線程,任務即被取出,任務隊列又恢復成空隊列。根據任務隊列是否爲空這個判斷條件來喚醒線程就要求有一個前提是,來任務,任務被線程池取出處理後,下一次任務纔會進來。當epoll監聽線程添加任務、喚醒一個等待線程、但是該線程沒有及時取出任務、又有新的任務添加進來時(任務隊列非空),就是出現喚醒一次,但是任務隊列有兩個甚至多個任務,這就導致這些任務只能有這個被喚醒的線程處理,並且再有任務進來,也不會執行喚醒,直到該線程處理完所有任務(若不能及時處理完,就會導致連接異常)。

socket套接字關閉問題
問題描述:某協議爲TCP短連接,執行一次數據交互即關閉socket套接字,在Client執行close時,Server端正常;在Client不主動關閉時,Server端的處理時,讀完套接字緩衝區所有數據,然後關閉套接字,readn函數封裝了recv讀取指定長度數據,要麼讀到指定數據,要麼套接字異常才返回。這就導致讀套接字緩衝區時,既不到指定數據,套接字又沒有被Client關閉,陷在死循環裏,佔據一個線程池線程。

問題分析:現使用的readn是本模塊自己封裝的,沒有select超時機制,原有readn函數,通過select設定超時機制爲2秒,超時套接字不能讀,則返回-1,不會陷入死循環;

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