jinfeng_wang

          G-G-S,D-D-U!

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks

              進程通信的概念最初來源于單機系統(tǒng),由于每個進程都在各自的地址范圍內(nèi)運行,為了保證兩個相互通信的進程之間既不互相干擾,又協(xié)調(diào)一致的工作,操作系統(tǒng)為進程通信提供了相應(yīng)設(shè)施,如UNIX BSD中的管道(pipe),有名管道(named pipe)和軟中斷信號(singal),UNIX system V的消息(message)、共享存儲區(qū)(shared memory)和信號量(semaphore)等,但都局限于用在本機進程之間通信。網(wǎng)間進程通信要解決的是不同主機進程間的通信問題(可把同機進程通信看作其中的特例)。為此,首先要解決的是網(wǎng)間進程標識問題。同一主機上,不同進程可以用進程號(pid)唯一標識。但在網(wǎng)絡(luò)環(huán)境下,各主機獨立分配的進程號不能唯一標識該進程。例如主機A賦予某進程號5,在B主機也可以存在5號進程,因此5號進程這句話就沒有意義了。其次,操作系統(tǒng)支持的網(wǎng)絡(luò)協(xié)議眾多,不同協(xié)議的工作方式不同,地址格式也不同。因此,網(wǎng)間進程通信還要解決多重協(xié)議的識別問題。為了解決上述問題,TCP/IP協(xié)議引入了下列幾個概念。

          端口

          網(wǎng)絡(luò)中可以被命名和尋址的通信端口是操作系統(tǒng)可分配的一種資源。按照OSI七層協(xié)議的描述,傳輸層與網(wǎng)絡(luò)層最大的區(qū)別是傳輸層提供進程通信能力。從這個意義上講,網(wǎng)絡(luò)通信的最終地址就不僅是主機地址了,還包括可以描述進程的某種標識。為此TCP/IP協(xié)議提出了協(xié)議端口的概念,用于標識通信的進程。

          端口是一種抽象的軟件結(jié)構(gòu),包括一些數(shù)據(jù)結(jié)構(gòu)和I/O緩沖區(qū)。應(yīng)用程序即進程通過系統(tǒng)調(diào)用與某端口建立連接(binding)后,傳輸層傳給該端口的數(shù)據(jù)都被相應(yīng)的進程所接收,相應(yīng)進程發(fā)給傳輸層的數(shù)據(jù)都從該端口輸出。在TCP/IP協(xié)議的實現(xiàn)中,端口操作類似于一般的I/O操作,進程獲取一個端口,相當于獲取本地唯一的I/O文件,可以用一般的讀寫原語訪問。

          類似于文件描述符,每個端口都擁有一個叫端口號的整數(shù)描述符,以區(qū)別不同端口。由于TCP/IP傳輸層的兩個協(xié)議TCP和UDP是兩個完全獨立的軟件模塊,因此各自的端口號也相互獨立。如TCP有一個255號端口,UDP也可以有一個255號端口,兩者并不沖突。

          端口號的分配是一個重要問題,有兩種基本分配方式:第一種叫全局分配這是一種集中分配方式,由一個公認的中央機構(gòu)根據(jù)用戶需要盡行統(tǒng)一分配,并將結(jié)果公布于眾,第二種是本地分配,又稱動態(tài)連接,即進程需要訪問傳輸層服務(wù)時,向本地操作系統(tǒng)提出申請,操作系統(tǒng)返回本地唯一的端口號,進程再通過合適的系統(tǒng)調(diào)用,將自己和該端口連接起來(綁定)。TCP/IP端口號的分配綜合了兩種方式。TCP/IP將端口號分為兩部分,少量的作為保留端口,以全局方式分配給服務(wù)進程。因此,每一個標準服務(wù)器都擁有一個全局公認的端口叫周知口,即使在不同的機器上,其端口號也相同。剩余的為自由端口,以本地方式進行分配。TCP和UDP規(guī)定,小于256的端口才能
          作為保留端口。

          地址

          網(wǎng)絡(luò)通信中的兩個進程分別在兩個不同的機器上。在互連網(wǎng)絡(luò)中,兩臺機器可以位于不同的網(wǎng)絡(luò),這些網(wǎng)絡(luò)通過網(wǎng)際互連設(shè)備(網(wǎng)關(guān),網(wǎng)橋,路由器)連接。因此需要三級尋址。

          1。某一主機與多個網(wǎng)絡(luò)相連,必須指定一特定網(wǎng)絡(luò)地址;
          2。網(wǎng)絡(luò)上美一臺主機應(yīng)有其唯一的地址;
          3。美一主機上的每一進程應(yīng)有在該主機上的唯一標識。

          主機地址就是IP啦,不必多說。進程唯一標識符是十六位整數(shù)端口號。網(wǎng)絡(luò)字節(jié)順序不同的計算機存放多字節(jié)值的順序不同,有的機器在起始地址存放低位字節(jié),有的則相反。為保證數(shù)據(jù)的正確性,在網(wǎng)絡(luò)協(xié)議中需指定網(wǎng)絡(luò)字節(jié)順序。TCP/IP協(xié)議使用16位整數(shù)和32位整數(shù)的高價先存格式,他們均含在協(xié)議的頭文件中。

          連接

          兩個進程間的通信鏈路稱為連接。連接在內(nèi)部表現(xiàn)為一些緩沖區(qū)和一組協(xié)議機制,在外部表現(xiàn)出比無連接高的可靠性。

          半相關(guān)

          綜上所述,網(wǎng)絡(luò)中用一個三元組可以在全局中唯一標是一個進程:
          (協(xié)議,本機地址,本地端口號)
          這樣一個三元組,叫做一個半相關(guān),他指定連接的每半部分。

          全相關(guān)

          一個完整的網(wǎng)間進程通信需要有兩個進程組成,并且只能使用同一種高層協(xié)議。也就是說TCP和UDP沒法通信。因此一個完整的網(wǎng)間進程通信需要一個五元組來標識:
          (協(xié)議,本機地址,本地端口號,遠地地址,遠地端口號)
          這樣一個五元組叫做一個全相關(guān)。

          客戶機/服務(wù)器模式

          在TCP/IP網(wǎng)絡(luò)應(yīng)用中,通信的兩個進程相互作用的主要模式是客戶機/服務(wù)器模式,即客戶端向服務(wù)器發(fā)出請求,服務(wù)器接收到請求后提供相應(yīng)的服務(wù)客戶機/服務(wù)器模式的建立基于以下兩點:首先,建立網(wǎng)絡(luò)的起因是網(wǎng)絡(luò)中軟、硬件資源、運算能力和信息不均等,需要共享,從而造就擁有眾多資源的主機提供服務(wù),資源較少的客戶請求服務(wù)這一非對等作用。其次,網(wǎng)間進程通信完全是異步的,相互通信的進程間既不存在父子關(guān)系,又不共享內(nèi)存緩沖區(qū),因此需要一種機制為希望通信的進程間建立一種聯(lián)系,為二者的數(shù)據(jù)交換提供同步,這就是基于客戶機/服務(wù)器模式的TCP/IP。

          客戶機/服務(wù)器模式在操作過程中采取的是主動請求方式:

          首先服務(wù)器方要啟動,并根據(jù)請求提供相應(yīng)服務(wù):
          1。打開一通信通道并告知本地主機,它愿意在某一公認地址端口上(周知口,如http為80)接受客戶請求。
          2。等待客戶請求到達該端口。
          3。接收到重復(fù)服務(wù)請求,處理該請求并發(fā)送應(yīng)答信號。接收并發(fā)服務(wù)請求,要激活一新進程來處理這個客戶請求。新進程處理此客戶請求,并不需要對其他請求做出應(yīng)答。服務(wù)完成后,關(guān)閉此新進程與客戶的通信鏈路,并終止。
          4。返回第二步,等待另外的客戶請求
          5。關(guān)閉服務(wù)器。

          客戶方:
          1。打開一通信通道,并連接到服務(wù)器所在主機的特定端口。
          2。向服務(wù)器發(fā)出服務(wù)請求報文,等待并接收應(yīng)答;繼續(xù)提出請求。
          3。請求結(jié)束后關(guān)閉通信通道并終止。
          從上面的描述過程可知:
          1。客戶與服務(wù)器進程的作用是非對稱的。因此編碼不同。
          2。服務(wù)進程一般是先于客戶請求啟動的。只要系統(tǒng)運行,該進程一直存在,直到正常終止或者強迫終止。

          套接字SOCKET和perl的socket編程

          在UNIX世界中,網(wǎng)絡(luò)應(yīng)用編程界面有兩類:BSD的套接字SOCKET和SYSTEM V的TLI.由于Sun公司采用了支持TCP/IP的BSD系統(tǒng),TCP/IP的應(yīng)用有了更大發(fā)展其網(wǎng)絡(luò)應(yīng)用編程界面Socket在網(wǎng)絡(luò)編程中已成為標準。并且也早已經(jīng)進入了MS的世界。

          TCP/IP的Socket提供下列三種類型的套接字

          1。流式套接字(SOCKET_STREAM)

          提供了一個面向連接,可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯,無重復(fù)的發(fā)送且按發(fā)送順序接收。內(nèi)設(shè)流量控制,避免數(shù)據(jù)流超限;數(shù)據(jù)被看作是字節(jié)流,無長度限制。FTP協(xié)議即采用流式套接字。

          2。數(shù)據(jù)報式套接字(SOCKET_DGRAM)

          提供了一個無連接服務(wù)。數(shù)據(jù)包以獨立包形式被發(fā)送,不提供無錯保證,數(shù)據(jù)可能丟失或重復(fù),并且接收順序無序。網(wǎng)絡(luò)文件系統(tǒng)NFS使用數(shù)據(jù)報式套接字。

          3。原始式套接字(SOCKET_RAW)

          該接口允許對較低層次協(xié)議,如IP、ICMP直接訪問。常用于檢驗新的協(xié)議實現(xiàn)或訪問現(xiàn)有服務(wù)中配置的新設(shè)備。

          基本套接字調(diào)用

          創(chuàng)建套接字--socket();
          綁定本機端口--bind();
          建立連接--connect(),accept();
          偵聽端口--listen();
          數(shù)據(jù)傳輸--send(),recv();
          輸入/輸出多路復(fù)用--select();
          關(guān)閉套接字--closesocket();

          不論何種語言,和socket打交道都是這一組調(diào)用只是在格式上有一點點差別。我只使用過c和perl,再加上這里又不讓出現(xiàn)與perl無關(guān)的東西,那下面就主要討論PERL的socket編程啦:

          創(chuàng)建建套接字:
          socket(SOC_VARIABLE,DOMAIN_FLAG,connectType,num) #相應(yīng)的C語言調(diào)用為so
          ckid=socket(af,type,protocol)
          參數(shù)含義如下:
          SOC_VARIABLE是用于建立套接的句柄,相當于c里面的sockid號;
          DOMAIN_FLAG叫域標記,在C里相當于af--address family,地址族。地址族和域是一個概念,其實就是平常所說的域。UNIX支持的域類型有
          AF-UNIX; UNIX內(nèi)部地址
          AF-INET; TCP/IP地址
          AF-NS; Xerox NS地址
          AF-APPLETALK; Apple的Appletalk地址
          而DOS/windows支持的域地址族只有AF-INET.所以大部分的socket編程都只用到它。
          connectType(c里的type)就是前面所說的三種socket類型。
          num相當于c里面的protocol那大家一看就明白了這是協(xié)議號,用來指定SOCKET請求所希望的協(xié)議,這個參數(shù)不一定起作用,當前兩個參數(shù)可以確定協(xié)議時可以取值為零。
          所以,一個完整的PERL的建立socket如下
          socket(THESCK,AF-INET,SOCKET_STREAM,getprotocolbyname('tcp'));
          #c語言: int sockid;
          # sockid = socket(AF-INET,SOCKET_STREAM,0);


          補充:
          Socket建立連接的過程

          linuxaid.com.cn 01-09-12 14:34 100p luster
          --------------------------------------------------------------------------------


          Socket建立連接的過程

          建立過程如下:(connection-oriented)
          server 方過程 client 方過程

          socket() socket()
          | |
          bind() bind()
          | |
          listen() |
          | |
          accept()<------------------connect()
          | |
          recv()/send() <----------> send()/recv()

          如果socket被置為block式,則connect()一直等到連接建立或出錯返回,否則立即返回.
          出錯時返回-1, 錯誤碼在errno中.
          如果讀寫一個沒有建立連接的socket則 返回-1, errno為EBADF

          posted on 2007-08-22 14:03 jinfeng_wang 閱讀(585) 評論(0)  編輯  收藏 所屬分類: ZZLinux
          主站蜘蛛池模板: 定兴县| 民和| 文山县| 江川县| 博爱县| 家居| 溧水县| 铁岭县| 信阳市| 嘉黎县| 崇州市| 盈江县| 新兴县| 崇信县| 高尔夫| 漾濞| 敦煌市| 桃江县| 广昌县| 大港区| 河池市| 钟山县| 河曲县| 澄江县| 彭泽县| 扎鲁特旗| 奎屯市| 海宁市| 平泉县| 镇雄县| 闽清县| 中江县| 巫溪县| 花莲市| 渝北区| 南投县| 兖州市| 印江| 玛沁县| 凤阳县| 平舆县|