【VS開發】socket編程原理

來源:互聯網
上載者:User

socket編程原理

1、問題的引入

1) 普通的I/O操作過程:

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

2) TCP/IP協議被整合到UNIX核心中

TCP/IP協議被整合到UNIX核心中時,相當於在UNIX系統引入了一種新型的I/O操作。UNIX使用者進程與網路通訊協定的互動作用比使用者進程與傳統的I/O裝置相互作用複雜得多。首先,進行網路操作的兩個進程在不同機器上,如何建立它們之間的聯絡。其次,網路通訊協定存在多種,如何建立一種通用機制以支援多種協議。這些都是網路應用編程介面所要解決的問題。 

3) 需要一種通用的網路編程介面:  獨立於具體協議和通用的網路編程

在UNIX系統中,網路應用編程介面有兩類:UNIX BSD的通訊端(socket)和UNIX System V的TLI。由於Sun公司採用了支援TCP/IP的UNIX BSD作業系統,使TCP/IP的應用有更大的發展,其網路應用編程介面──通訊端(socket)在網路軟體中被廣泛應用,至今已引進微機作業系統DOS和Windows系統中,成為開發網路應用軟體的強有力工具,本章將要詳細討論這個問題。  2、SOCKET編程基本概念

         開始使用通訊端編程之前,首先必須建立以下概念。  2.1 網間進程通訊  

進程通訊的概念最初來源於單機系統。由於每個進程都在自己的位址範圍內運行,為保證兩個相互連信的進程之間既互不干擾又協調一致工作,作業系統為進程通訊提供了相應設施,

如UNIX BSD有:管道(pipe)、具名管道(named pipe)非強制中斷訊號(signal)

UNIX system V有:訊息(message)、共用儲存區(shared memory)和訊號量(semaphore)等.

他們都僅限於用在本機進程之間通訊。網間進程通訊要解決的是不同主機處理序間的相互連信問題(可把同機進程通訊看作是其中的特例)。為此,首先要解決的是網間進程標識問題。同一主機上,不同進程可用進程號(process ID)唯一標識。但在網路環境下,各主機獨立分配的進程號不能唯一標識該進程。例如,主機A賦於某進程號5,在B機中也可以存在5號進程,因此,“5號進程”這句話就沒有意義了。 其次,作業系統支援的網路通訊協定眾多,不同協議的工作方式不同,地址格式也不同。因此,網間進程通訊還要解決多重協議的識別問題。 為瞭解決上述問題,TCP/IP協議引入了下列幾個概念。  1)連接埠 

網路中可以被命名和定址的通訊連接埠,是作業系統可分配的一種資源。 

按照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的連接埠號碼才能作保留連接埠。  2)地址 

網路通訊中通訊的兩個進程分別在不同的機器上。在互連網路中,兩台機器可能位於不同的網路,這些網路通過網路互連裝置(網關,橋接器,路由器等)串連。因此需要三級定址: 

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

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

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

通常主機地址由網路ID和主機ID組成,在TCP/IP協議中用32位整數值表示;TCP和UDP均使用16位連接埠號碼標識使用者進程。 

3)網路位元組順序 

不同的電腦存放多位元組值的順序不同,有的機器在起始地址存放低位位元組(小端序),有的存高位位元組(大端序)。為保證資料的正確性,在網路通訊協定中須指定網路位元組順序。TCP/IP協議使用16位整數和32位整數的高價先存格式,它們均含在協議標頭檔中。 詳解http://blog.csdn.net/hguisu/article/details/7449955#t1

4)串連 

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

5)半相關 

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

(協議,本地地址,本地連接埠號碼) 這樣一個三元組,叫做一個半相關(half-association),它指定串連的每半部分。  6)全相關 

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

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

2.2 服務方式  

在網路分層結構中,各層之間是嚴格單向依賴的,各層次的分工和協作集中體現在不同層之間的介面上。“服務”是描述不同層之間關係的抽象概念,即網路中各層向緊鄰上層提供的一組操作。下層是服務提供者,上層是請求服務的使用者。服務的表現形式是原語(primitive),如系統調用或庫函數。系統調用是作業系統核心向網路應用程式或高層協議提供的服務原語。網路中的n層總要向n+1層提供比n-1層更完備的服務,否則n層就沒有存在的價值。 在OSI的術語中,網路層及其以下各層又稱為通訊子網,只提供點到點通訊,沒有程式或進程的概念。而傳輸層實現的是“端到端”通訊,引進網間進程通訊概念,同時也要解決差錯控制,流量控制,資料排序(報文排序),串連管理等問題,為此提供不同的服務方式: 

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

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

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

2)順序 

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

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

在資料轉送過程中控制資料轉送速率的一種機制,以保證資料不被丟失。TCP協議提供這項服務。 

5)位元組流 

位元組流方式指的是僅把傳輸中的報文看作是一個位元組序列,不提供資料流的任何邊界。TCP協議提供位元組流服務。  6)報文 

接收方要儲存發送方的報文邊界。UDP協議提供報文服務。  7)全雙工系統/半雙工 

端-端間資料同時以兩個方向/一個方向傳送。 

8)緩衝/帶外資料 

在位元組流服務中,由於沒有報文邊界,使用者進程在某一時刻可以讀或寫任意數量的位元組。為保證傳輸正確或採用有流量控制的協議時,都要進行緩衝。但對某些特殊的需求,如互動式應用程式,又會要求取消這種緩衝。 在資料傳送過程中,希望不通過常規傳輸方式傳送給使用者以便及時處理的某一類資訊,如UNIX系統的中斷鍵(Delete或Control-c)、終端流量控制符(Control-s和Control-q),稱為帶外資料。邏輯上看,好象使用者進程使用了一個獨立的通道傳輸這些資料。該通道與每對串連的流相聯絡。由於Berkeley Software Distribution中對帶外資料的實現與RFC 1122中規定的Host Agreement不一致,為了將互操作中的問題減到最小,應用程式編寫者除非與現有服務互操作時要求帶外資料外,最好不使用它。 

2.3 客戶/伺服器模式  

在TCP/IP網路應用中,通訊的兩個進程間相互作用的主要模式是客戶/伺服器模式(Client/Server model),即客戶向伺服器發出服務要求,伺服器接收到請求後,提供相應的服務。客戶/伺服器模式的建立基於以下兩點:首先,建立網路的起因是網路中軟硬體資源、運算能力和資訊不均等,需要共用,從而造就擁有眾多資源的主機提供服務,資源較少的客戶請求服務這一非對等作用。其次,網間進程通訊完全是非同步,相互連信的進程間既不存在父子關係,又不共用記憶體緩衝區,因此需要一種機製為希望通訊的進程間建立聯絡,為二者的資料交換提供同步,這就是基於不同的客戶/伺服器模式的TCP/IP。 客戶/伺服器模式在工作過程中採取的是主動請求方式: 

伺服器方:

首先伺服器方要先啟動,並根據請求提供相應服務: 

1. 開啟一通訊通道並告知本地主機,它願意在某一公認地址上(周知口,如FTP為21)接收客戶請求; 

2. 等待客戶請求到達該連接埠; 

3. 接收到重複服務要求,處理該請求並發送應答訊號。接收到並發服務要求,要啟用一新進程來處理這個客戶請求(如UNIX系統中用fork、exec)。新進程處理此客戶請求,並不需要對其它請求作出應答。服務完成後,關閉此新進程與客戶的通訊鏈路,並終止。 

4. 返回第二步,等待另一客戶請求。 

5. 關閉伺服器  客戶方: 

1. 開啟一通訊通道,並串連到伺服器所在主機的特定連接埠; 

2. 向伺服器發服務要求報文,等待並接收應答;繼續提出請求...... 

3. 請求結束後關閉通訊通道並終止。 

從上面所描述過程可知: 

1. 客戶與伺服器處理序的作用是非對稱的,因此編碼不同。 

2. 服務進程一般是先於客戶請求而啟動的。只要系統運行,該服務進程一直存在,直到正常或強迫終止。 

2.4 通訊端類型  

TCP/IP的socket提供下列三種類型通訊端。  流式通訊端(SOCK_STREAM):

提供了一個連線導向、可靠的Data Transmission Service,資料無差錯、無重複地發送,且按發送順序接收。內設流量控

制,避免資料流超限;資料被看作是位元組流,無長度限制。檔案傳送協議(FTP)即使用流式通訊端。  資料報式通訊端(SOCK_DGRAM):

提供了一個無串連服務(UDP)。資料包以獨立包形式被發送,不提供無錯保證,

資料可能丟失或重複,並且接收順序混亂。網路檔案系統(NFS)使用資料報式通訊端。 

原始式通訊端(SOCK_RAW) :

該介面允許對較低層協議,如IP、ICMP直接存取。常用於檢驗新的協議實現或訪問現有服務中配置的新裝置。 

2.4 典型通訊端調用過程舉例   如前所述,TCP/IP協議的應用一般採用客戶/伺服器模式,因此在實際應用中,必須有客戶和伺服器兩個進 程,並且首先啟動伺服器,其系統調用時序圖如下。  連線導向的協議(如TCP)的通訊端系統調用如圖2.1所示:

 

伺服器必須首先啟動,直到它執行完accept()調用,進入等待狀態後,方能接收客戶請求。假如客戶在此前啟動,則connect()將返回出錯代碼,串連不成功。


 無連線協定(UDP)的通訊端調用如圖2.2所示:  


無串連伺服器也必須先啟動,否則客戶請求傳不到服務進程。無串連客戶不調用connect()。因此在資料發送之前,客戶與伺服器之間尚未建立完全相關,但各自通過socket()和bind()建立了半相關。發送資料時,發送方除指定本地通訊端號外,還需指定接收方通訊端號,從而在資料收發過程中動態地建立了全相關。 

執行個體 

本執行個體使用連線導向協議的客戶/伺服器模式,其流程如圖2.3所示: 


伺服器方程式: 

[cpp]  view plain  copy  print ? /* File Name: streams.c */    #include <winsock.h>    #include <stdio.h>    #define TRUE 1    /* 這個程式建立一個通訊端,然後開始無限迴圈;每當它通過迴圈接收到一個串連,則列印出一個資訊。  當串連斷開,或接收到終止資訊,則此串連結束,程式再接收一個新的串連。命令列的格式是:streams */          main( )    {    int sock, length;    struct sockaddr_in server;    struct sockaddr tcpaddr;    int msgsock;    char buf[1024];    int rval, len;       /* 建立通訊端 */    sock = socket(AF_INET, SOCK_STREAM, 0);    if (sock < 0) {    perror(“opening stream socket”);    exit(1);    }   

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.