關閉AcceptEx緩衝區導致延遲增加問題

經測試,在AcceptEx函數指針投遞accept請求的時候如果把接收緩衝區的大小設置爲零,那麼server端消息到client端延遲會增加10ms左右(各機器性能不同...)    上對比圖

關閉了緩衝區的server端

 

client端

咱們先不看第一個client鏈接,因爲程序啓動耗時的原因,所以拿第二個舉例, 第二個執行WSASend函數後的時間爲1586760772134(1900年到現在的毫秒數),  客戶端的到達時間爲1586760772144, 共10毫秒, 由於本人做過多次試驗,所以確定時間在10毫秒左右浮動,  接下來我們看正常緩衝區大小的收發用時

帶緩衝區的server端

 

client端


大家可以看到,server端的發送消息時間和client端的接收消息時間都爲1586761584231,0毫秒的延遲, 證明之前10毫秒的延遲是因爲我們關閉了接收緩衝區造成的,不知道系統是怎麼操作的..
       但是,很重要的是,設置接收緩衝區大小爲0有一個好處,就是可以防止拒絕服務攻擊(連接上後就不發消息的client),因爲設置緩衝區大小爲0後windows一收到連接請求就會通過GetQueuedCompletionStatus通知我們, 那麼我們就可以儘快的做出處理,防止攻擊, 而如果我們不設置緩衝區大小爲0的話,windows的機制就會將兩個操作合併爲一個,哪兩個操作呢,那就是accept和客戶端發出的第一組數據,寫過iocp的都知道,客戶端連接的時候GetQueuedCompletionStatus並不會通知我們,而是在第一組數據發出的時候才通知我們,這是易用也是不易用的地方。
       之前還在網上看過一種方法,就是不設置緩衝區大小爲0,但是定時用getsockopt()函數(選項參數爲SO_CONNECT_TIME)來檢查AcceptEx()裏守候的套接字,可以看到套接字的連接時間或者狀態,但是,如果是在高流量的情況下,那麼這種方案就有點不太管用,還會阻塞其他用戶的連接,所以,我建議還是設置緩衝區爲0,就算會有一點延遲,但是會讓我們的服務器更加安全。

      另外針對連接後的client端,在網上也看到一個比較好的處理方案,就是投遞WSARecv後先將連接後客戶端放入verctor或者list中,設定一個時間間隔定時檢查超時的連接,及時關閉並刪除其數據,如果同一ip出現次數過多就判斷爲惡意連接加入黑名單,如果接收到數據結構中的socket發出的數據的時候再將其從中移除放入正常的管理列表。

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