前言:本文只介紹了有關unix網路程式設計的理論知識,具體的應用和例子在稍後的博文中將更新
第一章 簡介
乙個簡單的伺服器程式步驟:
說明:1.建立tcp套介面
2.**伺服器的眾所周知埠
3.把套介面變換成監聽套介面
4.接受客戶連線,傳送應答,伺服器程序在呼叫accept函式後處於睡眠狀態,它等待客戶的連線和核心對它的接受。tcp連線使用三路握手來建立,當握手完畢,accept函式返回,其返回值是乙個已連線描述字的新描述字。
osi模型
第二章 傳輸層:tcp和udp
udp:使用者資料報協議
我們稱udp提供無連線服務,因為udp客戶與伺服器不必存在長期的關係。例如:乙個udp客戶可以建立乙個套介面並傳送乙個資料報給乙個伺服器,然後立即用同乙個套介面傳送另乙個資料報給另乙個伺服器。同樣,乙個udp伺服器可以用用以個udp套介面從5個不同的客戶一連串接受5個資料報。
tcp:傳輸控制協議
首先,tcp提供客戶與伺服器的連線;
其次,tcp提供可靠性;
第三,tcp通過給所傳送資料的每乙個位元組關聯乙個序列號進行排序;
第四,tcp提供流量控制;tcp總是告訴對方它能夠接受多少位元組的資料,這稱為通告視窗。
最後,tcp連線時全雙工的;
tcp連線的建立和終止
建立乙個tcp連線時,會發生下述情形:
1、伺服器端必須做好準備接受外來的連線。這通常通過 socket(), bind(), listen() 三個函式來完成的。我們稱之為 被動開啟(passive open).
2、客戶端通過呼叫connect發起主動開啟(active open)。這導致客戶端tcp傳送syn同步分節。它告訴伺服器客戶端在(待建立的)連線中傳送的資料的初始化序列號。通用syn分節不攜帶資料,
3、伺服器必須確認(ack) 客戶端的syn,同時自己也得傳送乙個syn分節,它含有伺服器將在統一連線中傳送的資料的初始化序號。伺服器在單個分節中傳送syn和對客戶端syn的ack確認。
4、客戶端必須確認伺服器的syn。
建立tcp連線的日常系統模擬是**系統[nemeth 1997].socket函式等同於有**可用.bind用於告訴其他人你的**號碼,讓他們可以向你打**.listen是開啟**振鈴,它使你可以聽到乙個外來的**.connect要求你知道另一方的**號碼並撥打它.accept是被呼叫回**.從accept返回客戶的標識(即客戶的ip位址和埠號)類似於讓**機的呼叫者id功能部件顯示打**人的**號碼.然而有點不同的地方是:從accept返回客戶的標識是在建立連線以後,而呼叫者id功能部件顯示打**人的**號碼是在我們選擇接或不接**之前.如果使用網域名稱系統(第9章),那麼提供了一種類似於**薄的服務.gethostbyname類似於在**薄查詢個人的**號碼.gethostbyaddr則類似於有一種**薄按**號碼排序
syn洪水攻擊
假設乙個c向s傳送了syn後無故消失了,那麼s在發出syn+ack應答報文後是無法收到c的ack報文的(第三次握手無法完成),這種情況下s一般會重試(再次傳送syn+ack給客戶端)並等待一段時間後丟棄這個未完成的連線,這段時間的長度我們稱為syn timeout,一般來說這個時間是分鐘的數量級(大約為30秒-2分鐘);乙個c出現異常導致s的乙個執行緒等待1分鐘並不是什麼很大的問題,但如果有乙個惡意的攻擊者大量模擬這種情況,s將為了維護乙個非常大的半連線列表而消耗非常多的資源----數以萬計的半連線,即使是簡單的儲存並遍歷也會消耗非常多的cpu時間和記憶體,何況還要不斷對這個列表中的ip進行syn+ack的重試.實際上如果s的tcp/ip棧不夠強大,最後的結果往往是堆疊溢位崩潰---即使s的系統足夠強大,s也將忙於處理攻擊者偽造的tcp連線請求而無暇理睬客戶的正常請求(畢竟c的正常請求比率非常之小),此時從正常客戶的角度看來,s失去響應,這種情況我們稱作:伺服器端受到了syn flood攻擊(syn洪水攻擊).
tcp連線的終止:
1、某個應用程式首先呼叫close,主動關閉(active close) 該端的tcp於是傳送乙個fin分節,表示資料傳送完畢。
2、接收到這個fin的對端執行被動關閉(passive close)。這個fin是tcp確認。它的接收也作為乙個檔案結束符(end of file) 傳遞給接收端的應用程式(放在排隊等候應用程序接收的任何其他資料之後),因為fin的接收意味著接收端應用程式在相應連線上再無額外資料可以接收。
3、一段時間以後,接收到這個檔案結束符的應用程序將呼叫close關閉它的套接字。這導致它的tcp也傳送乙個fin。
4、接收這個最終find額原傳送端tcp(即執行主動關閉的一端)確認這個fin
注意:執行主動關閉的那一端(客戶端)進入
time_wait
狀態。time_wait狀態:
tcp中有關網路程式設計最不容易理解的是它的time_wait狀態。執行主動關閉的那端進入這種狀態,該端點停留在這種狀態的持續時間是最長分節生命週期(msl)的兩倍,有時候稱之為2msl。
存在time_wati狀態有兩個理由:
1、可靠地實現tcp全雙工連線的終止。
2、允許老的重複分節在網路中消逝。
第乙個理由的解釋如下:假設tcp連線終止的最終的ack丟失,伺服器將重發最終的fin,因此客戶必需維護狀態資訊,以允許它重發最終的ack。要是不維護狀態資訊,它將響應以rst,而伺服器則把該分節解釋成乙個錯誤。
要理解存在time_wait狀態的第二個理由,我們假設在12.106.32.254的埠1500和206.168.112.219的埠21之間有乙個tcp連線。我們關閉這個連線後,在以後某個時候又重新建立起相同的ip和埠之間的tcp連線。後乙個連線稱為前乙個連線的化身,因為它的ip位址和埠號都相同。tcp必須防止來自某個連線的老的重複分組在該鏈結已經終止後再現,從而被誤解成屬於同一連線的新化身。為做到這一點,tcp將不給處於time_wait狀態的連線啟動新的化身。既然time_wait狀態持續的時間是2msl,這就足夠允許某個方向上的分組最多存活msl秒即被丟棄,另乙個方向上的應答最多存活msl秒也被丟棄。通過實施這個規則,我們能夠保證每當成果建立乙個tcp連線時,來自該連線先前化身的老的重複分組都已在網路中消逝。
埠分配:
unix系統有保留埠的概念,它是小於1024的任何埠。這些埠只能分配給超級使用者程序的套介面。所有眾所周知的埠都為保留埠,因此分配這些埠的伺服器啟動時必須具有超級使用者的特權。
套介面對:
標識每個端點的兩個值(ip位址和埠號)通常稱為乙個套介面。
套介面傳送緩衝區:
上面是tcp的緩衝區,從乙個tcp套介面的write呼叫成功返回僅僅表示我們可以重新使用應用程序的緩衝區,它並不告訴我們對方的tcp或對方應用程序已接受到資料。而udp是不可靠的,它不必儲存應用程序的資料拷貝,因此無需乙個真正的傳送緩衝區。
UNIX網路程式設計之SO REUSEADDR關鍵字
1 一般來說 乙個埠釋放後會等待兩分鐘之後才能再被使用 so reuseaddr 是讓埠釋放後立即就可以被再次使用。so reuseaddr 用於對tcp 套接字處於 time wait 狀態下的 socket 才可以重複繫結使用。server 程式總是應該在呼叫 bind 之前設定 so reus...
UNIX網路程式設計之環境配置
開始學習 unix網路程式設計 輸入第乙個程式後,遇到各種錯誤,先將解決方案記錄如下。mkdir home yourname download 建立存放壓縮檔案的目錄 tar xzvf unpv13e.tar.gz 解壓 ls al 檢視該目錄下的檔案 cd unpv13e 進入unpv13e ca...
Unix網路程式設計 傳輸層 TCP和UDP
第二章 傳輸層 tcp udp和sctp 1 使用者資料報協議 udp 1 描述 應用程式往乙個udp套接字寫入一條訊息,該訊息隨後被封裝到乙個udp資料報,又被封裝到乙個ip資料報,然後發往目的地 2 特點 缺乏可靠性 資料報到達目的地,但是檢驗和檢測有錯誤,或者該資料報在網路傳輸被丟棄,不會自動...