Socket編程基本原理

Socket編程基本原理

1  問題的引入

        UNIX系統的I/O命令集,是從Maltics和早期系統中的命令演變出來的,其模式爲打開一讀/寫一關閉(open-write-read-close)。在一個用戶進程進行I/O操作時,它首先調用“打開”獲得對指定文件或設備的使用權,並返回稱爲文件描述符的整型數,以描述用戶在打開的文件或設備上進行I/O操作的進程。然後這個用戶進程多次調用“讀/寫”以傳輸數據。當所有的傳輸操作完成後,用戶進程關閉調用,通知操作系統已經完成了對某對象的使用。

        TCP/IP協議被集成到UNIX內核中時,相當於在UNIX系統引入了一種新型的I/O操作。UNIX用戶進程與網絡協議的交互作用比用戶進程與傳統的I/O設備相互作用複雜得多。首先,進行網絡操作的兩個進程在不同機器上,如何建立它們之間的聯繫?其次,網絡協議存在多種,如何建立一種通用機制以支持多種協議?這些都是網絡應用編程界面所要解決的問題。

        在UNIX系統中,網絡應用編程界面有兩類:UNIX  BSD的套接字(socket)和UNIX System V的TLI。由於Sun公司採用了支持TCP/IP的UNIX  BSD操作系統,使TCP/IP的應用有更大的發展,其網絡應用編程界面──套接字(socket)在網絡軟件中被廣泛應用,至今已引進微機操作系統DOS和Windows系統中,成爲開發網絡應用軟件的強有力工具,本章將要詳細討論這個問題。

2  套接字編程基本概念

        在開始使用套接字編程之前,首先必須建立以下概念。

2.1  網間進程通信

        進程通信的概念最初來源於單機系統。由於每個進程都在自己的地址範圍內運行,爲保證兩個相互通信的進程之間既互不干擾又協調一致工作,操作系統爲進程通信提供了相應設施,如UNIX  BSD中的管道(pipe)、命名管道(named pipe)和軟中斷信號(signal),UNIX system V的消息(message)、共享存儲區(shared memory)和信號量(semaphore)等,但都僅限於用在本機進程之間通信。網間進程通信要解決的是不同主機進程間的相互通信問題(可把同機進程通信看作是其中的特例)。爲此,首先要解決的是網間進程標識問題。同一主機上,不同進程可用進程號(process ID)唯一標識。但在網絡環境下,各主機獨立分配的進程號不能唯一標識該進程。例如,主機A賦於某進程號5,在B機中也可以存在5號進程,因此,“5號進程”這句話就沒有意義了。

        其次,操作系統支持的網絡協議衆多,不同協議的工作方式不同,地址格式也不同。因此,網間進程通信還要解決多重協議的識別問題。

        爲了解決上述問題,TCP/IP協議引入了下列幾個概念。

 

端口

        網絡中可以被命名和尋址的通信端口,是操作系統可分配的一種資源。

        按照OSI七層協議的描述,傳輸層與網絡層在功能上的最大區別是傳輸層提供進程通信能力。從這個意義上講,網絡通信的最終地址就不僅僅是主機地址了,還包括可以描述進程的某種標識符。爲此,TCP/IP協議提出了協議端口(protocol port,簡稱端口)的概念,用於標識通信的進程。

        端口是一種抽象的軟件結構(包括一些數據結構和I/O緩衝區)。應用程序(即進程)通過系統調用與某端口建立連接(binding)後,傳輸層傳給該端口的數據都被相應進程所接收,相應進程發給傳輸層的數據都通過該端口輸出。在TCP/IP協議的實現中,端口操作類似於一般的I/O操作,進程獲取一個端口,相當於獲取本地唯一的I/O文件,可以用一般的讀寫原語訪問之。

        類似於文件描述符,每個端口都擁有一個叫端口號(port number)的整數型標識符,用於區別不同端口。由於TCP/IP傳輸層的兩個協議TCP和UDP是完全獨立的兩個軟件模塊,因此各自的端口號也相互獨立,如TCP有一個255號端口,UDP也可以有一個255號端口,二者並不衝突。

        端口號的分配是一個重要問題。有兩種基本分配方式:第一種叫全局分配,這是一種集中控制方式,由一個公認的中央機構根據用戶需要進行統一分配,並將結果公佈於衆。第二種是本地分配,又稱動態連接,即進程需要訪問傳輸層服務時,向本地操作系統提出申請,操作系統返回一個本地唯一的端口號,進程再通過合適的系統調用將自己與該端口號聯繫起來(綁紮)。TCP/IP端口號的分配中綜合了上述兩種方式。TCP/IP將端口號分爲兩部分,少量的作爲保留端口,以全局方式分配給服務進程。因此,每一個標準服務器都擁有一個全局公認的端口(即周知口,well-known port),即使在不同機器上,其端口號也相同。剩餘的爲自由端口,以本地方式進行分配。TCP和UDP均規定,小於256的端口號才能作保留端口。

 

地址

        網絡通信中通信的兩個進程分別在不同的機器上。在互連網絡中,兩臺機器可能位於不同的網絡,這些網絡通過網絡互連設備(網關,網橋,路由器等)連接。因此需要三級尋址:

1. 某一主機可與多個網絡相連,必須指定一特定網絡地址;

2. 網絡上每一臺主機應有其唯一的地址;

3. 每一主機上的每一進程應有在該主機上的唯一標識符。

        通常主機地址由網絡ID和主機ID組成,在TCP/IP協議中用32位整數值表示;TCP和UDP均使用16位端口號標識用戶進程。

 

網絡字節順序

        不同的計算機存放多字節值的順序不同,有的機器在起始地址存放低位字節(低價先存),有的存高位字節(高價先存)。爲保證數據的正確性,在網絡協議中須指定網絡字節順序。TCP/IP協議使用16位整數和32位整數的高價先存格式,它們均含在協議頭文件中。

 

連接

        兩個進程間的通信鏈路稱爲連接。連接在內部表現爲一些緩衝區和一組協議機制,在外部表現出比無連接高的可靠性。

 

半相關

        綜上所述,網絡中用一個三元組可以在全局唯一標誌一個進程:

                (協議,本地地址,本地端口號)

        這樣一個三元組,叫做一個半相關(half-association),它指定連接的每半部分。

 

全相關

        一個完整的網間進程通信需要由兩個進程組成,並且只能使用同一種高層協議。也就是說,不可能通信的一端用TCP協議,而另一端用UDP協議。因此一個完整的網間通信需要一個五元組來標識:

                (協議,本地地址,本地端口號,遠地地址,遠地端口號)

        這樣一個五元組,叫做一個相關(association),即兩個協議相同的半相關才能組合成一個合適的相關,或完全指定組成一連接。

2.2  服務方式

        在網絡分層結構中,各層之間是嚴格單向依賴的,各層次的分工和協作集中體現在相鄰層之間的界面上。“服務”是描述相鄰層之間關係的抽象概念,即網絡中各層向緊鄰上層提供的一組操作。下層是服務提供者,上層是請求服務的用戶。服務的表現形式是原語(primitive),如系統調用或庫函數。系統調用是操作系統內核向網絡應用程序或高層協議提供的服務原語。網絡中的n層總要向n+1層提供比n-1層更完備的服務,否則n層就沒有存在的價值。

        在OSI的術語中,網絡層及其以下各層又稱爲通信子網,只提供點到點通信,沒有程序或進程的概念。而傳輸層實現的是“端到端”通信,引進網間進程通信概念,同時也要解決差錯控制,流量控制,數據排序(報文排序),連接管理等問題,爲此提供不同的服務方式:

 

面向連接(虛電路)或無連接

        面向連接服務是電話系統服務模式的抽象,即每一次完整的數據傳輸都要經過建立連接,使用連接,終止連接的過程。在數據傳輸過程中,各數據分組不攜帶目的地址,而使用連接號(connect ID)。本質上,連接是一個管道,收發數據不但順序一致,而且內容相同。TCP協議提供面向連接的虛電路。

        無連接服務是郵政系統服務的抽象,每個分組都攜帶完整的目的地址,各分組在系統中獨立傳送。無連接服務不能保證分組的先後順序,不進行分組出錯的恢復與重傳,不保證傳輸的可靠性。UDP協議提供無連接的數據報服務。

        下面給出這兩種服務的類型及應用中的例子:

 

服務類型

服     務

例     子

面向連接        

可靠的報文流

可靠的字節流

不可靠的連接

文件傳輸(FTP)

遠程登錄(Telnet)

數字話音

無連接

不可靠的數據報    

有確認的數據報

請求-應答

電子郵件(E-mail)

電子郵件中的掛號信

網絡數據庫查詢

 

順序

        在網絡傳輸中,兩個連續報文在端-端通信中可能經過不同路徑,這樣到達目的地時的順序可能會與發送時不同。“順序”是指接收數據順序與發送數據順序相同。TCP協議提供這項服務。

 

差錯控制

        保證應用程序接收的數據無差錯的一種機制。檢查差錯的方法一般是採用檢驗“檢查和(Checksum)”的方法。而保證傳送無差錯的方法是雙方採用確認應答技術。TCP協議提供這項服務。

 

流控制

        在數據傳輸過程中控制數據傳輸速率的一種機制,以保證數據不被丟失。TCP協議提供這項服務。

 

字節流

        字節流方式指的是僅把傳輸中的報文看作是一個字節序列,不提供數據流的任何邊界。TCP協議提供字節流服務。

 

報文

        接收方要保存發送方的報文邊界。UDP協議提供報文服務。

 

全雙工/半雙工

        端-端間數據同時以兩個方向/一個方向傳送。

 

緩存/帶外數據

        在字節流服務中,由於沒有報文邊界,用戶進程在某一時刻可以讀或寫任意數量的字節。爲保證傳輸正確或採用有流控制的協議時,都要進行緩存。但對某些特殊的需求,如交互式應用程序,又會要求取消這種緩存。

        在數據傳送過程中,希望不通過常規傳輸方式傳送給用戶以便及時處理的某一類信息,如UNIX系統的中斷鍵(Delete或Control-c)、終端流控制符(Control-s和Control-q),稱爲帶外數據。邏輯上看,好象用戶進程使用了一個獨立的通道傳輸這些數據。該通道與每對連接的流相聯繫。由於Berkeley Software Distribution中對帶外數據的實現與RFC 1122中規定的Host Agreement不一致,爲了將互操作中的問題減到最小,應用程序編寫者除非與現有服務互操作時要求帶外數據外,最好不使用它。


發佈了270 篇原創文章 · 獲贊 12 · 訪問量 52萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章