TCP/IP 協定與 Internet 網路:第八章 TCP Socket 程式介面  上一頁           下一頁

 

翻轉工作室:粘添壽

 

8-3 Socket 連接方式

利用 Socket 介面發展網路應用程式有:虛擬電路和電報傳輸兩個主要通訊模式,以下我們以 Client/Server 架構分別介紹兩種通訊模式。

8-3-1 虛擬電路模式

『虛擬電路』(Virtual Circuit模式表示通訊雙方傳輸資料之前,必須先建立通訊鏈路,因此所採用的傳輸層為連接導向的 TCP 協定。圖 8-4 是利用 Socket 程式庫,使用 TCP 協定建立的 Client/Sever 模式之基本架構,圖中 Server 端,首先呼叫 socket() 開啟一個通訊端點,接下來以 bind() 設定連接之傳輸埠口,並以 listen() 功能呼叫設定該 Socket 通訊端點為聆聽狀態(Listen Mode),準備接收對方要求連線,最後呼叫 accept() 等待 Client 端的連線。同樣的,Client 端也以 socket() 呼叫建立通訊端點,並以 bind() 連接到傳輸埠口,此時 Client 便可用 connect() 功能呼叫要求連接到 Server 端。雙方連線成功之後,便可以用 read() write() 來互相傳輸資料,最後以 close() 結束此連線。

8-4  Socket 的虛擬電路模式

在虛擬電路中有:同步(Synchronous)和非同步(Asynchronous)兩種傳輸模式。同步傳輸模式表示執行 Socket 程式後,還未得到回應時,會繼續等待一直到有回應才會回主程式,因此又稱為『阻斷模式』(Blocking Mode。譬如,Server 端執行 accept() 程式,會一直等待到有連線到達,才會回應給主程式;而非同步模式表示執行 Socket 程式會即時回應給主程式,不論是否取得資料,又稱為『非阻斷模式』(Nonblocking Model

另一種情況,在同步傳輸模式中執行 read() 程式,如果接收緩衝器上有資料,便會直接讀取並返回主程式,但如果緩衝器上沒有資料,則會一直等待到連線對方傳送資料過來,才會返回主程式。非同步傳輸模式則不然,不論緩衝器上是否有資料可以讀取,都會即時返回主程式。由此可以見,同步傳輸只適合一對一的通訊端點傳輸,但大部分的 Client/Server 架構,Server 端必須能同時接受多個 Client 端的要求連線,同步傳輸便不適合。一般開啟連接導向的通訊端點,內定值都是同步傳輸模式,如果通訊端點欲能夠接受多點連接(一般都是 Server 端),必須將 Socket 設定為非同步傳輸模式。又從另一觀點來看,執行 read() 程式時,是由緩衝器上讀取資料,Socket ID 也如同一般檔案識別碼一樣,因此我們可以利用一般檔案控制程式 fcntl() 來設定。因此設定 Socket 為非同步傳輸模式的方法非常簡單,開啟 Socket 後,以 fcntl() 程式將 FNDELAY 旗號加入到 Socket IDsd)內即可,程式格式如下:

fcntl(sd, F_SETFL, FNDELAY);

        如欲將 Socket 由非同步傳輸模式改為同步傳輸模式,也就是將旗號 FNDELAY 消除,其程式格式如下:

int flags;

 

flags = fcntl(sd, F_GETFL, 0);

fcntl(sd, F_SETFL, (flags & ~FNDELAY));

參數 sd Socket ID,第一個 fcntl() 程式是讀取 Socket 上的旗號值,而第二個 fcntl() 是作為取消 FNDELAY 旗號使用。

Socket 被設定成非同步傳輸模式之後,必須能夠隨時接收到資料的到達,以下有兩種方法:

(1) 週期性的執行 read() 功能呼叫,隨時準備接收及時到達之資料。

(2) 設定 Socket 具有發送訊息的功能,譬如,當一般資料到達時,會發送 SIGIO 訊號給主程式,再由主程式執行 read() 程式來讀取,或當快速資料(Expedited Data)到達時,會發送給 SIGURG 給主程式。

8-3-2 電報傳輸模式

        8-5 為建立在 UDP 協定上的『電報傳輸』(Datagram模式,也是 Client/Server 的基本架構。Server Client 端分別以 socket() 功能呼叫開啟通訊端點,並以 bind() 連結到傳輸埠口位址,其中 Client 端是否執行 bind() 為選項項目。雙方以 recvfrom() sendto() 互相傳送資料。

8-5 Socket 的電報傳輸模式

        由圖 8-5 中表示,電報傳輸的預定值也是同步傳輸模式,也就是說,當某一方執行 recvfrom() 時,必需等待到收到對方傳送過來資料,才會返回到主程式,否則會一直等待著(Blocking Model)。如同虛擬電路一樣,我們可以利用 fcntl() 將其設定成非同步傳輸模式,程式格式如下:

fcntl(sd, F_SETFL, FNDELAY)

參數 sd Socket 的識別碼,可以是 Server 端或 Client 端。取消 FNDELAY 也如同虛擬電路一樣,不再另述。

 

 

<GOTOP>