書
linux高效能伺服器程式設計+原始碼(帶書籤) 31.8m
問題socket伺服器開發中的so_reuseaddr選項與讓人心煩的time_wait
回想一下,linux下的time_wait大概是2分鐘,這樣也合情合理。那麼沒有釋放掉的資源是什麼呢,是埠嗎?機智的我立刻決定做實驗找出答案。啟動伺服器程式,在與客戶建立連線之後,kill掉伺服器。飛快地在terminal裡輸入命令:netstat -an|grep 9877。這裡9877是我伺服器打算繫結的埠。果然:
結果顯示9877埠正在被使用,並處於tcp中的time_wait狀態。再過兩分鐘,我再執行命令netstat -an|grep 9877,世界清靜了,什麼都沒有。
終於找到了答案:果然是time_wait在搗鬼。
我遇到的情況正好符合情況1,並且書上說了:「所有tcp伺服器都應該指定本套接字選項,以允許伺服器在這種情形下被重新啟動。」那麼試試看嘍。
unix network programming
乙個很特別的tcp選項tcp_defer_accept
經過測試發現,設定tcp_defer_accept選項後,伺服器受到乙個connect請求後,作業系統不會accept,也不會建立io控制代碼。作業系統應該在若干秒,(但肯定遠遠大於上面設定的1s) 後,會釋放相關的鏈結。但沒有同時關閉相應的埠,所以客戶端會一直以為處於鏈結狀態。如果connect後面馬上有後續的傳送資料,那麼伺服器會呼叫accept接收這個鏈結埠。
感覺了一下,這個埠設定對於connect鏈結上來而又什麼都不幹的攻擊方式處理很有效。我們原來的**都是先允許鏈結,然後再進行超時處理,比他這個有點out了。不過這個選項可能會導致定位某些問題麻煩。
裡面 val 的單位是秒,注意如果開啟這個功能,kernel 在 val 秒之內還沒有收到資料,不會繼續喚醒程序,而是直接丟棄連線。
將sin_addr設定為inaddr_any"的含義是什麼?
inaddr_any
轉換過來就是0.0.0.0,泛指本機的意思,也就是表示本機的所有ip,因為有些機子不止一塊網絡卡,多網絡卡的情況下,這個就表示所有網絡卡ip位址的意思。
比如一台電腦有3塊網絡卡,分別連線三個網路,那麼這台電腦就有3個ip位址了,如果某個應用程式需要監聽某個埠,那他要監聽哪個網絡卡位址的埠呢?
如果繫結某個具體的ip位址,你只能監聽你所設定的ip位址所在的網絡卡的埠,其它兩塊網絡卡無法監聽埠,如果我需要三個網絡卡都監聽,那就需要繫結3個ip,也就等於需要管理3個套接字進行資料交換,這樣豈不是很繁瑣?
所以出現inaddr_any,你只需繫結inaddr_any,管理乙個套接字就行,不管資料是從哪個網絡卡過來的,只要是繫結的埠號過來的資料,都可以接收到。
epoll:epolllt和epollet的區別
概念:level-triggered :水平觸發,預設模式
edge-triggered :邊緣觸發
比如redis用lt模式,nginx用et模式
通知模式:
lt模式時,事件就緒時,假設對事件沒做處理,核心會反覆通知事件就緒
et模式時,事件就緒時,假設對事件沒做處理,核心不會反覆通知事件就緒
事件通知的細節:
1.呼叫epoll_ctl,add或者mod事件epollin
lt:如果此時快取區沒有可讀資料,則epoll_wait不會返回epollin,如果此時緩衝區有可讀資料,則epoll_wait會持續返回epollin
et:如果此時快取區沒有可讀資料,則epoll_wait不會返回epollin,如果此時緩衝區有可讀資料,則epoll_wait會返回一次epollin
2.呼叫epoll_ctl,add或者mod事件epollout
lt:如果不呼叫epoll_ctl將epollout修改為epollin,則epoll_wait會持續返回epollout(前提條件是寫緩衝區未滿)
et:epoll_wait只會返回一次epollout
針對tcp的測試詳請,都是non-blocking:
1.listenfd設定為lt
表現:當3次握手完成,如果不進行accept操作,那麼核心會反覆通知
2.listenfd設定為et
linux 下epoll與執行緒池結合使用的簡單例項
linux中send函式msg_nosignal異常訊息
最後問了下我們的張總,問題剛給他說完,他便說他以前也遇到這個問題,給我找到了他以前的解決方案。解決方法是使用 send 函式時候在最後乙個引數上加 msg_nosignal 標記即可。於是自己更改傳送函式 write 為 send 並新增 msg_nosignal 標誌,重新編譯,執行,中斷 server,果然這個問題被很瀟灑的解決了,感謝張總的英明神武。
參考乙個博文的介紹
linux 下當連線斷開,還傳送資料的時候,不僅 send() 的返回值會有反映,而且還會向系統傳送乙個異常訊息,如果不作處理,系統會出 brokepipe,程式會退出,這對於伺服器提供穩定的服務將造成巨大的災難。為此,send() 函式的最後乙個引數可以設定為 msg_nosignal,禁止 send() 函式向系統傳送常訊息。
書《windows網路程式設計》
《題名/著者: windows 網路程式設計/ (美)athony jones,(美)jim ohlund著
叢編題名: 微軟 .net 程式設計師系列
isbn號: 7-302-05947-0
出版項: 北京 清華大學出版社 2002.10
載體資訊: 23cm ⅹⅲ,458頁 cny78.00
附註項: 本書著重於windows xp中革新的聯**性,同時包含了對c#程式語言的支援。本書還介紹了最新的網際協議:ipv4和ipv6,以及可靠ip多播協議。 讀者物件:vb或c++ 的程式開發人員。
伺服器資訊收集
version 1.2 modify date 2013 05 21 說明 該指令碼可以獲取計算機名,網域名稱,ip位址,作業系統版本,cpu名稱 單顆cpu核心數量 cpu個數,記憶體大小 gb 單塊磁碟大小,計算機序列號,製造商,計算機型號 該指令碼先將計算機資訊輸出到txt檔案中,然後再自動輸...
伺服器資訊收集
version 1.2 modify date 2013 05 21 說明 該指令碼可以獲取計算機名,網域名稱,ip位址,作業系統版本,cpu名稱 單顆cpu核心數量 cpu個數,記憶體大小 gb 單塊磁碟大小,計算機序列號,製造商,計算機型號 該指令碼先將計算機資訊輸出到txt檔案中,然後再自動輸...
TypePerf收集伺服器效能
typeperf.exe這個命令列工具可以收集伺服器效能資料 1.查詢和資料庫jinridomesticorder相關的效能引數 typeperf qx sqlserver databases find testr 2.查詢和資料庫jinridomesticorder相關的效能引數並匯出 typep...