• 沒有找到結果。

第三章 背景知識

3.5 Socket

Socket 是源自柏克萊加州大學(UC Berkeley)為 Berkeley Software Distribution (BSD) 的 UNIX 4.1 版所添加的網路通訊系統 呼叫,它是一個簡單的 TCP/IP 網路程式設計介面(API),用來發展 網路應用程式相當容易,這套 API 常特稱為 Berkeley Sockets;由 於 UNIX 的流行,採用 Socket 的使用者不斷增加,並隨著越來越多 商業版本的 UNIX 以 BSD 的 UNIX 原始碼為基礎而發展,連帶的使 Socket 成為最通用的網路程式設計介面。由於 Socket 的普遍性,在 某一版本 UNIX 上的網路應用程式,不必作太大的修改,就能輕易 的移植到另一版本上。

爾後,Microsoft 為了要替 Windows 提供一套 TCP/IP API,便根 據 Berkeley Sockets 界面加以改造延伸,定義出 Windows Sockets,

常簡稱為 WinSock。

Socket 的概念與檔案處理代碼(File Handle)的概念相當類似。一 個 Socket 就是一個通訊的端點,以一個小的正整數表示。Socket 並 不是 TCP 或 UDP 的埠號,而是一個處理代碼(Handle),代表了網路 協定中的一大組資料。這些與 Socket 相關的資料,包括了如 TCP 連線中,收發雙方的 IP 位址及埠號,以及目前的連線狀況。當網路 上有資料來到,TCP 或 UDP 會依資料表頭處的埠號來分送資料給應 用程式,緩衝起來的資料,也可以用 Socket 當成鍵值自網路協定堆 疊中取出。與 File Handle 相同,Socket 有其相關的「狀態」存在。

舉例來說,File Handle 可以用來開檔或關檔;當檔案開啟後,File Handle 便可用來讀檔或寫檔。Socket 也有這類的狀態,但是一個網 路連線遠比一個檔案要複雜,因此 Socket 有更多的函式來處理不同 的狀態。與 File Handle 不同的是,不能在「開啟」Socket 後立刻使 用它。

在運用 Socket 時,要看連線是資料流(Stream)或是資料串 (Datagram),以及應用程式的工作角色是伺服器(Server)或客戶端 (Client)而定。

Socket 主要分為兩類:Datagram 及 Stream。Socket 的種類在 Socket 開啟時就需要設定,而後便不能再更改。Datagram Socket 使 用 UDP datagram 來傳送資料,Stream Socket 則使用 TCP。用 UDP 傳送到達的資料,可以保證一定是正確的,但它並不保證一定送到,

因為 UDP Datagram 可能會送丟、送錯而被丟棄,或是到達的順序 與送出的順序不同,在這些情形下,UDP 並不會有所反應。Stream Socket 較適合用來建立雙向的 TCP 連線,TCP 保證寫入 Socket 的資 料無誤,並且會以原寫入時的順序抵達目的地。如果資料流中部分 的封包在傳送過程中毀損、次序錯亂或者是送丟了,TCP 會察覺有 問題發生,並重新發送或將封包重新排序來補救。由於 TCP 保證提 供無錯誤的傳送管道,因此適用於需要傳送大量資料,且要求結果 完全正確的狀況下。因此大多的 Socket 都是以 Stream 的服務方式來 交換資料,在我們的系統中也是用此方法。

在網路程式設計的領域中,”伺服器”指的是等待客戶端主動連 線,並提供服務的一個程式;而要求連線的程式,即稱為”客戶端”。

在 Socket 程式設計上,其兩者的差別在於起始連線與等待連線時運 作方式明顯的不同。圖 3.3 表示了 Stream 式 Socket 做為客戶端時的 狀態變化圖,圖 3.4 則是做為伺服器時的狀態變化。

圖 3.3 客戶端的 Stream Socket 運作方式

圖 3.4 伺服器的 Stream Socket 運作方式

使用 Stream Socket 時,不論客戶端或伺服器程式,都在 Socket 開 啟後,須使用 bind 函式將它與本地位址結合在一起,意義上即為把 Socket 代號與代表本地位址的網路介面鏈結在一起。這可用家中電 話來比喻,「結合」等於宣告你想要用這隻電話,隨時準備使用它。

若是接電話這一方,「結合」指定了你要接的電話是這一隻,並在有 人打電話來後準備回話。

在 Socket 開啟並結合後,伺服器和客戶端的程式設計方式,開 始有所不同。就客戶端而言,下一步就要準備與遠端連線,這時要 用 connect 函式,其參數包括遠端主機的位址及埠號,如果 connect 的回傳值正確,Socket 即與遠端主機連線,並可用此 Socket 收發資 料。connect 函式就像撥一通電話,先將對方的電話號碼(即 IP 位址 與 PORT)告訴接線生,再由接線生撥通電話。

而伺服器程式中,當 Socket 與本地位址結合完成後,程式必須 以 listen 函式來表示他開始等待接受連線,最後再以 accept 函式接 受連線。accept 會回傳一個新的 Socket,此 Socket 的本地端參數與 原 Socket 相同,但會填入遠地端參數,如起始連線之遠端主機的位 址及埠號。之後便可利用 send 及 recv 命令,對這個新的 Socket 進 行資料傳輸,這時原本的 Socket 仍可以繼續接受其他客戶端的連線。

listen 及 accept 兩個函數,分別相當於「等待電話響」及「接聽 電話」的動作。listen 告訴 TCP 有連線要求時通知程式,accept 則告 訴 TCP,程式接受建立連線。不過須特別注意的是,accept 後是產 生一個新的 Socket 來供此客戶端與伺服器通訊。TCP 以本地及遠端

的位址和埠號來辨識一個連線,如此,在伺服器位址及埠號相同的 情形下,只要客戶端有不同的 IP 與 PORT,就可在同一個伺服器中 同時支援多組連線。

當 Socket 連線後,就可以用 send 及 recv 來傳送及接收資料,

這就像是通電話的兩人開始交談。當程式完成資料傳遞後,便要以 closesocket 來關閉 Socket,這步驟釋放 Socket 代號相關的狀態資訊 並釋放 Socket。Socket 關閉後,便不可再以此 Socket 呼叫任何程式。

相關文件