遇到乙個因socket未關閉引發的檔案控制代碼用完問題

2021-07-04 02:32:10 字數 2229 閱讀 6140

「愛提踢斯」專案最近遇到乙個問題,當ftp伺服器磁碟沒有空間時,裝置會不斷復位——這是測試人員反饋的。我們拿到log後,看到乙個通訊所用的檔案開啟失敗。不斷列印too many open file,然後超時裝置復位。同時我們看到資料庫檔案開啟失敗,無法寫入資料。乙個現象,看到好幾處問題。還是從最初的表現來入手。雖然把bug指派給別人,但從時間、進度上考慮,週末還是去加班。而最後,解決了問題。根據老夫目測,是ftp的socket未關閉引起的。

可見,預設是1024。

下面用**來說明一下問題。**如下:

/**

系統一次允許最大的檔案控制代碼為1024。

open foobar file for: 340

open bar file for: 340

open foo file for: 341

open foobar file failed: : too many open files

open bar file failed: : too many open files

# ulimit -a

...open files (-n) 1024

...*/

#include #include #include #include #include int foo(void)

; char read_buf[5] = ;

fd = open("/tmp/foo.txt",o_rdwr|o_creat,0666);

if(fd < 0)

printf("open foo file for: %d\n", cnt++);

return 0;

}int bar(void)

; char read_buf[5] = ;

fd = open("/tmp/bar.txt",o_rdwr|o_creat,0666);

if(fd < 0)

printf("open bar file for: %d\n", cnt++);

return 0;

}int foobar(void)

; char read_buf[5] = ;

fd = open("/tmp/foobar.txt",o_rdwr|o_creat,0666);

if(fd < 0)

printf("open foobar file for: %d\n", cnt++);

return 0;

}int main(void)

return 0;

}

要檢視這個程序占用檔案控制代碼數,先獲取該程序pid:

# ps -ef | grep a.out     

root     17835  7615 17 23:01 pts/1    00:00:00 ./a.out

我們檢視該程序檔案控制代碼最大值:

# cat /proc/17835/limits | grep "files"

max open files            1024                 4096                 files  

和系統預設值一樣。檢視已占用值:

# ll /proc/17835/fd | wc -l 

1027

我們看到,已經占用上千個控制代碼,一直未釋放。當達到系統最大值時,就會報too many open files的錯誤。

匆匆已然四載,不曾想到,當年剛入職搞ftp的我,竟然會埋下地雷,讓今天的我不幸踩中。在沒有離職情況下,只好義無反顧地去解決bug。——而這個bug,正是因為未關閉socket造成的。

ftp客戶端的實現,是需要開啟2個socket的,乙個是命令通道,乙個是資料通道。在伺服器沒有磁碟空間情況下,write資料是返回錯誤的,使用ftp模組者認為是無法登陸,下次會再次嘗試登陸——在這種情況下,登陸是正常的,只是無法寫資料。但每次登陸,都會建立命令通道的socket,這導致了socket的洩漏,不會關閉,因為使用者並沒有呼叫logout函式退出登陸。另乙個問題是最主要的,每次寫資料時,要建立資料通道的socket,但在出錯時,並沒有關閉資料通道的socket,而是直接返回。這再次導致了socket洩漏。找到了原因,解決起來就好辦了。

自從知道可以檢視某個程序占用的檔案控制代碼,我去看看以前的裝置,發現有個別檔案占用控制代碼較多——也就幾十個。目測是只開啟但未關閉。出於熱心,我把情況在部門群裡說了,至於後續的事,因為那些不是我的職責範圍,不敢越趄代庖。

2015.8.1 李遲

如何優雅地關閉乙個socket

如何優雅地關閉乙個socket 1.關閉socket時究竟做了什麼 關閉socket分為主動關閉 active closure 和被動關閉 passive closure 兩種情況。前者是指有本地主機主動發起的關閉 而後者則是指本地主機檢測到遠端主機發起關閉之後,作出回應,從而關閉整個連線。其狀態圖...

ArcMap遇到了乙個問題,需要關閉

最近在使用 arcmap 時候遇到乙個問題,在進行編輯資料時候,突然報錯,然後提示 arcmap 遇到了乙個問題,需要關閉 介面如下 之後再開啟 arcmap 的時候就無法正常啟動,總是提示遇到問題無法正常開啟 arcmap 實在沒辦法,我只好解除安裝了 arcgis desktop 9.3.1 重...

乙個socket原始碼

vc編寫伺服器 式的聊天室 2009 9 11 本文參考了 visual c 6.0完全自學手冊 中的示例 一 流程說明 客戶端客戶端建立流式套接字 呼叫connection向伺服器傳送連線請求 連線成功後使用建立與之關聯的的csocketfile物件和carchive物件 使用carchive物件...