顧客服務員程序設計要點_第1頁
顧客服務員程序設計要點_第2頁
顧客服務員程序設計要點_第3頁
顧客服務員程序設計要點_第4頁
顧客服務員程序設計要點_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

n更多企業(yè)學院: 中小企業(yè)管理全能版183套講座+89700份資料總經(jīng)理、高層管理49套講座+16388份資料中層管理學院46套講座+6020份資料國學智慧、易經(jīng)46套講座人力資源學院56套講座+27123份資料各階段員工培訓學院77套講座+ 324份資料員工管理企業(yè)學院67套講座+ 8720份資料工廠生產(chǎn)管理學院52套講座+ 13920份資料財務管理學院53套講座+ 17945份資料銷售經(jīng)理學院56套講座+ 14350份資料銷售人員培訓學院72套講座+ 4879份資料第四章 顧客服務員程序設計4.1 網(wǎng)絡服務模式近年來,在信息系統(tǒng)中廣泛使用的信息共享模型是顧客/服務器模型,這種計算模式迅速取代了以主機為主導的集中式計算方法。顧客/服務器計算具有自己的一組行業(yè)術語。表4-1列出了一些術語,這些術語經(jīng)常出現(xiàn)在對顧客/服務器產(chǎn)品和應用的描述中。表4-1 顧客/服務器術語術語說明應用程序編程接口(API)一組支持顧客/服務器之間進行相互通信的函數(shù)和可調(diào)用程序顧客一個服務的請求方,通常是一個末端系統(tǒng),能夠從服務器處查詢信息中間件一組驅(qū)動程序、應用程序編程接口或其它軟件,用于改善顧客/服務器之間的連接關系數(shù)據(jù)庫是一種把信息訪問限制于按照搜索條件選擇數(shù)據(jù)的數(shù)據(jù)庫服務器是一臺計算機,通常是一臺高性能工作站、小型機或大型機,擁有供網(wǎng)絡中眾多用戶訪問的信息結(jié)構化查詢語言(SQL)由IBM開發(fā)、由ANSI標準化的一種語言,用于對關系數(shù)據(jù)庫的尋址、創(chuàng)建、更新和查詢顧客/服務器環(huán)境中最基本元素是顧客和服務器。顧客通常是PC或工作站,為端用戶提供非常友好的界面,例如微軟的Windows等。服務器為顧客提供一組共享的用戶服務程序。最常見的是數(shù)據(jù)庫服務器,服務器能夠使很多顧客共享對同一信息源的訪問。除了顧客和服務器,組成顧客/服務器模型的第三個基本要素是網(wǎng)絡系統(tǒng)。顧客。服務器計算是分布式計算。用戶、應用程序和資源是分布式的,用來響應實際業(yè)務請求,并且它們通過局域網(wǎng)、廣域網(wǎng)或Internet連接起來。顧客/服務器模型與分布式處理有很多不同點,主要有:l 在用戶自己的系統(tǒng)中為該用戶提供界面友好的應用程序。這使得用戶可以在很大程度上控制時間安排和計算機使用類型,并使得部門管理者具有響應本地需求的能力。l 盡管應用是分散的,但仍然強調(diào)數(shù)據(jù)的集中以及很多網(wǎng)絡管理和使用功能的集中。l 對于用戶組織和廠商來說,他們有一個共同的承諾,使系統(tǒng)開放和模塊化。這意味著用戶在選擇產(chǎn)品和混合使用來自眾多廠家的設備時具有很大的選擇性。l 網(wǎng)絡互聯(lián)是操作的基礎,網(wǎng)絡管理和網(wǎng)絡安全在組織和操作系統(tǒng)中具有很高的優(yōu)先權。4.1.1 顧客/服務器應用顧客/服務器體系結(jié)構的核心是應用程序級任務在顧客和服務器之間的分配。圖4-1給出了這個模型的一般情況。無論是顧客還是服務器,最基本的軟件是運行在硬件平臺上的操作系統(tǒng),顧客的平臺和操作系統(tǒng)可能和服務器的不同。事實上,在網(wǎng)絡環(huán)境下,可能會有很多不同類型的顧客平臺和操作系統(tǒng)以及很多類型的服務器平臺和操作系統(tǒng)。只要特定的顧客和服務器共享相同的通信協(xié)議并支持相同的應用程序,低層的細節(jié)不必考慮。顧客服務器請求/應答表示服務應用邏輯(服務器部分)應用邏輯(顧客部分)通信軟件通信軟件協(xié)議交互服務器操作系統(tǒng)顧客操作系統(tǒng)硬件平臺硬件平臺圖4-1 顧客/服務器體系結(jié)構使顧客和服務器能夠交互的基礎是通信軟件,這種軟件主要例子是TCP/IP。所有這些支持軟件(通信軟件和操作系統(tǒng))的主要任務是,為分布式的應用程序提供一個基本結(jié)構。在理論上,應用程序所執(zhí)行的實際功能可以針對顧客和服務器分割開來,方法是使平臺和網(wǎng)絡資源達到最優(yōu)化。且使用戶執(zhí)行各種任務及相互之間合作使用共享資源的能力達到最優(yōu)化。在某些情況下,這些都要求大批的應用程序軟件在服務器上執(zhí)行,而在其它一些情況下,多數(shù)應用程序邏輯上位于顧客端。顧客/服務器環(huán)境能夠成功的一個基本因素是用戶將系統(tǒng)當作一個整體而與之打交道的方式。因此,顧客端的用戶界面的設計是十分重要的。在大多數(shù)顧客/服務器系統(tǒng)中,都突出強調(diào)了要提供易于使用、易于學習、功能強大并且靈活的圖形用戶界面(GUI)。4.1.2 顧客/服務器應用程序分類在顧客/服務器的通用框架中,對顧客和服務器的工作劃分有許多不同的實現(xiàn)方法。圖4-2針對數(shù)據(jù)庫應用說明了可以以多種方式來分配處理過程,圖中概括了數(shù)據(jù)庫應用的一些主要選項。當然也存在其它的劃分方法,并且對于其它不同類型的應用選項也可能具有不同的特點。服務器顧客表示邏輯應用邏輯數(shù)據(jù)庫邏輯DBMS(a) 基于主機的處理服務器顧客表示邏輯應用邏輯數(shù)據(jù)庫邏輯DBMS(b) 基于服務器的處理服務器顧客表示邏輯應用邏輯應用邏輯數(shù)據(jù)庫邏輯DBMS(c) 合作處理服務器顧客表示邏輯應用邏輯數(shù)據(jù)庫邏輯數(shù)據(jù)庫邏輯DBMS(d) 基于顧客的處理圖4-2 顧客/服務器應用程序分類圖4-2描述了4種網(wǎng)絡服務類型,它們分別是:l 基于主機的處理:基于主機的處理并不是真正的用戶普遍認同的顧客/服務器計算。而且,基于主機的處理是指傳統(tǒng)的大型機環(huán)境,實質(zhì)上所有的處理都是在一臺中心主機上完成的。用戶接口通常是通過一臺啞終端,即使用戶在使用一臺微機,用戶終端也是局限于終端仿真器的角色。l 基于服務器的處理:顧客/服務器配置的最基本的一類,即顧客端主要負責提供圖形化用戶界面,而實質(zhì)上所有的處理都是在服務器上完成的。這種配置是早期的顧客/服務器模式,尤其是部門級系統(tǒng)的典型。在這種配置背后的基本原理是用戶工作站最適合提供良好的用戶界面,并且數(shù)據(jù)庫和應用程序很容易在中心系統(tǒng)上維護。l 基于顧客的處理:在另一個極端,實際上所有應用處理可以全部在顧客端完成。一個例外是最適合在服務器上執(zhí)行的數(shù)據(jù)確認例程和其它數(shù)據(jù)庫邏輯功能。一般地,某些更復雜的數(shù)據(jù)庫邏輯功能都位于顧客端。這種結(jié)構可能是當今使用最普遍的顧客/服務器方式,使用戶能夠使用適合本地需要的應用。l 合作處理:在合作處理配置方式中,應用處理是以最優(yōu)化的方式來執(zhí)行的,充分利用了顧客和服務器兩方面的優(yōu)勢以及數(shù)據(jù)的分布性。這樣一種配置在設置和維護方面更加復雜,但從長遠看,這種配置類型比其它類型可以為用戶更好的服務質(zhì)量和更高的網(wǎng)絡效率。圖4-2c和圖4-2d對應的配置情況是在顧客端上有相當大的一部分負載。這種所謂的“胖顧客”(fat client)模型已經(jīng)被像Powersoft公司的PowerBuilder和Gupta公司的SQL Windows這樣的應用程序開發(fā)工具所采用。使用這些工具開發(fā)的應用在范圍上是部門級的,支持25到150個用戶。胖顧客的主要優(yōu)點是它充分利用了桌面功能,卸除了服務器上的應用處理并使它們更加有效,不易發(fā)生瓶頸。然而,胖顧客策略也存在許多缺點,隨著更多功能累加起來,快速地超出了桌面機器的容量,迫使機器進行升級。如果模型擴充,超出了部門的界限,合并了很多用戶,則必須安裝高性能局域網(wǎng)來支持瘦服務器和胖顧客之間大量的數(shù)據(jù)傳輸。最后,維護、升級或替換分布于數(shù)十臺或百臺桌面機的應用程序是非常困難的。圖4-2b代表了一種瘦顧客(thin client)的方式,這種方式更近似地模仿了傳統(tǒng)的以主機為中心的方式,常常是使應用程序從大型機環(huán)境發(fā)展到分布式環(huán)境的移植途徑,是目前流行的Internet網(wǎng)絡環(huán)境下的應用程序開發(fā)模式。4.1.3 三層顧客/服務器結(jié)構傳統(tǒng)的顧客/服務器結(jié)構包括兩級(或稱兩層):顧客層和服務器層。近年來,一種三層結(jié)構變得日益流行,如圖4-3所示。在這種結(jié)構中,應用軟件分布在三種類型的機器上:用戶機器、中間層服務器以及后端服務器。用戶機器是顧客,在三層結(jié)構中,它一般是一種瘦型顧客。中間層機器基本上是位于顧客和很多后端數(shù)據(jù)庫服務器之間的連接器。中間層機器能夠轉(zhuǎn)換協(xié)議,從一種類型的數(shù)據(jù)庫系統(tǒng)映像為另一種。另外,中間層機器能夠融合來自不同數(shù)據(jù)源的結(jié)果。最后,中間層機器也可以充當桌面應用程序和后端應用程序之間的連接器。在中間層服務器和后端服務器之間的交互也遵從顧客/服務器的模式。因此,中間層服務器同時充當著顧客和服務器。顧客中間層服務器(應用程序服務器)后端服務器后端服務器圖4-3 三層顧客/服務器結(jié)構4.1.4 中間件顧客/服務器產(chǎn)品的開發(fā)和使用缺少標準化,使得實現(xiàn)集成的、多廠商的、企業(yè)范圍的顧客/服務器配置變得困難,因為顧客/服務器方式的大多數(shù)優(yōu)點與其模塊化以及將平臺和應用程序混合、協(xié)調(diào)起來提供商業(yè)解決辦法的能力緊密相連的,這種互操作問題必須得到很好的解決。為了獲得顧客/服務器的優(yōu)點,開發(fā)者必須開發(fā)一組工具,為跨越所有平臺訪問系統(tǒng)資源提供唯一的方法和形式。這使程序員能夠構件這樣的應用程序:在不同的PC 機和工作站上所見所感相同,而且無論數(shù)據(jù)在什么位置都使用相同的方法來訪問數(shù)據(jù)。滿足這一要求的最普遍的方法是,在上層應用程序和下層通信軟件和操作系統(tǒng)之間使用標準編程接口和協(xié)議。這種標準化的接口和協(xié)議稱為中間件(middleware)。具有了標準的編程接口,在不同的服務器類型和工作站類型上實現(xiàn)相同的應用就很容易了。這對于用戶來說具有明顯的好處,而廠商也受到市場的驅(qū)動來提供這樣的接口。主要原因是用戶購買應用程序而不是服務器;用戶將只選擇那些運行了他們希望的應用程序的服務器。需要標準化的協(xié)議將這些不同的服務器接口與需要訪問它們的顧客連接起來。目前已經(jīng)有很多中間件軟件包,從非常簡單的到非常復雜的。它們所具有的共同特點是隱藏不同網(wǎng)絡協(xié)議和操作系統(tǒng)的復雜性和不一致性。顧客和服務器廠商一般都提供了很多非常流行的中間件軟件包供選擇,這樣,用戶可以決定一個特定的中間件策略,然后從各個廠商那里匯集裝置,來支持這個策略。圖4-4給出了在顧客/服務器結(jié)構中中間件的作用。注意,中間件具有顧客端組件和服務器端組件兩部分,中間件的基本目的是使位于顧客端的應用程序或用戶能夠訪問服務器上的各種服務,同時不需考慮服務器之間的差別。對于特定的應用領域,結(jié)構化查詢語言(SQL)提供一種標準化的方式,由本地或遠程的用戶或應用程序訪問關系數(shù)據(jù)庫。然而關系數(shù)據(jù)庫廠商盡管支持SQL,但他們將自己專有的擴展加到了SQL中。這樣使廠商能夠讓眾多產(chǎn)品有所差別,但也產(chǎn)生了潛在的不兼容性。顧客工作站表示服務服務器中間件交互應用邏輯中間件中間件應用服務通信軟件通信軟件協(xié)議交互服務器操作系統(tǒng)顧客操作系統(tǒng)硬件平臺硬件平臺圖4-4 在顧客/服務器結(jié)構中中間件的作用4.1.5 文件cache的一致性當使用文件服務器時,文件I/O的性能相對于局部文件訪問具有顯著的下降,主要原因是網(wǎng)絡帶來的延遲。為了減少這種性能下降,系統(tǒng)可以使用文件高速緩沖器來保存最近訪問的文件記錄。由于局部性原理,使用本地文件高速緩沖器可以減少必須進行的遠程服務器訪問次數(shù)。文件通道服務器通道顧客cache服務器cache磁盤通道磁盤通道顧客磁盤服務器磁盤圖4-5 文件高速緩存機制圖4-5描述了一種典型的文件高速緩存機制,用于在網(wǎng)絡互連的工作站組上高速緩存文件。當進程要進行文件訪問時,請求首先提交到進程所在的工作站的cache中,如果在那里未得到滿足,則該請求或者傳遞給本地磁盤,或者傳遞給文件服務器。在服務器端,首先查詢服務器上的cache,如果沒有命中,則訪問文件服務器的磁盤。雙重高速緩存的方法用于減少通信量和磁盤I/O。當cache中總能含有遠程數(shù)據(jù)的精確副本時,這些cache是一致的。Cache之間可能會變得不一致。這是因為遠程數(shù)據(jù)已經(jīng)改變,而相應的已經(jīng)陳舊的本地cache副本并沒有被廢棄。當一個顧客修改了也被其它顧客高速緩存了的文件時,這種情況就會發(fā)生。這個問題實際上存在于兩個層次上,如果顧客采用了將任何變化立即寫回服務器的文件中的策略,則任何具有文件相關部分的cache副本的其它顧客將具有陳舊的數(shù)據(jù)。如果顧客延遲了將變化寫回服務器,則問題就更糟了,因為服務器本身也只是擁有文件的舊版本,且將請求讀至服務器的新文件也可能擁有陳舊的數(shù)據(jù)。保持本地cache副本是遠程數(shù)據(jù)的最新變化的問題就是cache的一致性問題。解決cache一致性的最簡單的方法是使用文件上鎖技術,以防止多個顧客對文件的同時訪問。這在損害性能和靈活性的前提下保證了一致性。Sprite系統(tǒng)中的機制提供了更好的方法,任何數(shù)目的遠程進程可以打開一個文件,用于讀入和生成它們自己的顧客cache,但是當一個針對服務器的打開文件請求要求寫入訪問而其它進程都是為讀訪問而打開這個文件的,則服務器要采取兩步行動:第一,它告知寫入進程,盡管它保留了一個cache,但是必須在發(fā)生更新時立即寫回所有改變的塊。系統(tǒng)在一個時刻最多只能有一個這樣的顧客。第二,服務器告知所有使文件打開的讀進程,該文件已不再是可緩存的了。4.1.6 服務員類型在本章所舉的各個例子中都必須指定進程的類型(顧客/服務員)和協(xié)議的類型(面向連接/無連接),而對于服務員則還要進一步指出是并發(fā)型服務員還是反復型服務員(通常顧客并不在乎是和并發(fā)型服務員還是和反復型服務員通信)。這樣,就給出4種可能組合如表4-1。表4-1服務員類型服務員類型反復型并發(fā)型面向連接不常用有代表性無連接有代表性不常用 4.2標準Internet服務和常見的應用4.2.1 標準Internet服務表4-2列出了TCP/IP多數(shù)實現(xiàn)都提供的一些標準服務。表中的所有服務同時使用TCP和UDP提供,并且這兩個協(xié)議的端口號也相同。表4-2 標準TCP/IP服務名字TCP端口UDP端口RFC說明 Echo(回射)77862服務器返回顧客發(fā)送的數(shù)據(jù)Discard(丟棄)99863服務器丟棄顧客發(fā)送的數(shù)據(jù)Daytime(時間/日期)1313867服務器返回可讀的日期和時間Chargen(字符生成)1919864TCP服務器發(fā)送連續(xù)的字符流,直到顧客終止連接。每當顧客發(fā)送一個數(shù)據(jù)報,UDP就返回一個包含隨機數(shù)量字符的數(shù)據(jù)報。time(時間)3737868服務器返回一個32位二進制數(shù)值的時間。這個數(shù)值表示從1900年1月1日子時(UTC)以來所流逝的秒數(shù)。這些服務通常由Unix系統(tǒng)中的inetd守護進程提供。使用標準的telnet顧客程序很容易測試這些功能。這五個功能由inetd內(nèi)部處理的功能,對于TCP版本的echo、discard和chargen服務器由inetd派生出來后作為子進程運行,這是因為它們都要運行到相應的顧客終止連接為止。另外兩個TCP服務器time和daytime并不需要派生,因為它們的服務實現(xiàn)起來非常簡單(取得當前的時間和日期,把它格式化后輸出,在關閉連接),因此它們由inetd直接處理。所有五個UDP服務的處理都不需要fork調(diào)用,因為它們只就引發(fā)它們的顧客數(shù)據(jù)報生成并回應最多一個數(shù)據(jù)報,因此它們是由inetd直接處理的。4.2.2 常見的Internet應用表4-3總結(jié)了各種常見的Internet應用程序?qū)f(xié)議的使用情況。表4-3 各種常見的Internet應用程序?qū)f(xié)議的使用情況應用程序IPICMPUDPTCPPing*Traceroute*OSPF(路由協(xié)議)*RIP(路由協(xié)議)*BGP(路由協(xié)議)*BOOTP(引導協(xié)議)*DHCP(引導協(xié)議)*NTP(時間協(xié)議)*TFTP(簡單的FTP)*SNMP(網(wǎng)絡管理)*SMTP(電子郵件)*Telnet(虛擬終端)*FTP(文件傳輸)*HTTP(Web)*NNTP(網(wǎng)絡新聞)*DNS(域名系統(tǒng))*NFS(網(wǎng)絡文件系統(tǒng))*Sun RPC(遠程過程調(diào)用)*表中,前兩個應用程序Ping和Traceroute是診斷應用程序,它們使用ICMP協(xié)議。Traceroute構造自己的UDP分組來發(fā)送,并讀ICMP的應答。緊接著是三個比較流行的路由協(xié)議,它們展示了路由協(xié)議使用的各種傳輸協(xié)議。OSPF采用原始套接口直接使用IP,而RIP使用UDP,BGB則使用TCP。下面5個是基于UDP的應用程序,接著5個應用程序使用TCP,最后3個是同時使用UDP和TCP的應用程序。4.3 并發(fā)服務器4.3.1 套接口對一個TCP連接的套接口對(socket pair)是一個定義該連接的兩個端點的四元組:本地IP地址、本地TCP端口號、遠程IP地址和遠程TCP端口號。套接口對唯一標識一個互連網(wǎng)上的TCP連接。標識每個端點的兩個值(IP地址和端口號)通常稱為一個套接口。可以把套接口對的概念擴展到UDP,即使UDP是面向無連接的。當描述套接口函數(shù)(bind、connenct、getpeername等)時,注明它們在說明套接口對中那個值,例如bind函數(shù)要求應用程序說明本地IP和本地端口,既可以是TCP套接口,也可以是UDP套接口。4.3.2 并發(fā)服務器對于像時間/日期這樣簡單的服務器,使用迭代服務器(iterative server)具有較好的服務質(zhì)量;但是,當顧客的請求需要長時間服務時,不可能讓一個服務器長時間地為一個顧客服務,為了提供網(wǎng)絡服務質(zhì)量,而是同時為多個顧客服務。Unix系統(tǒng)下編寫一個并發(fā)應用程序最簡單的方法就是為每個顧客均fork一個子進程。下面代碼給出了一個典型的并發(fā)服務器程序框架。 pid_t pid;int listenfd,connfd;listenfd=Socket(); /* create a socket */Bind(listenfd,);Listen(listenfd,LISTENQ); /* listen from the socket */For(;)Connfd=Accept(listenfd,);If(pid=Fork()=0) /* create a child process */Close(listenfd); /* child closes listening socket */Doit(connfd); Close(connfd);Exit(0); /* child terminates */Close(connfd); /* parent closes connected socket */并發(fā)服務器中主服務器循環(huán)派生子進程來處理每個新的連接。并發(fā)服務器讓派生的子進程來處理顧客的請求。具體過程如圖4-6所示。(監(jiān)聽套接口)*.21.*.*請求(1)服務器顧客Fork(2)服務器(子進程),1300,,21連接(3), 21,,1300(已連接套接口)圖4-6 并發(fā)服務器讓子進程處理顧客請求的服務圖中有一個服務器,它的IP地址為。服務器在它的眾所周知的端口(例如21端口)上執(zhí)行被動打開,并等待顧客的請求。這里使用符號*.21.*.*指出服務器的套接口對。服務器在任意本地接口(第一個星號)的端口21上等待連接請求。遠程IP地址和遠程端口沒有指定,用“*.*”表示。這里的星號稱為通配(wildcard)符。如果運行服務器的主機有多個IP地址,服務器可以說明它只接受到達某個特定本地接口的外來連接。這是指定一個接口或者任意接口的選擇。服務器不能指定多個地址的列表。通配的本地地址表示“任意”接口。此時,必須區(qū)別服務器的監(jiān)聽套接口和已連接套接口。這里,已連接套接口使用和監(jiān)聽套接口相同的端口號:21。同時,一旦建立連接,以連接的本地套接口的本地地址()隨即填入。如果下一個顧客(假設IP地址為23,端口號為1301)隨即也提出了服務請求,服務器就再派生第二個子進程對它進行服務,這時建立連接的四元組為, 21,23,1301。服務器能夠區(qū)別這兩個連接:第一個連接的套接口對和第二個連接的套接口對是不同的。通過上面的例子可以看出,TCP無法僅僅通過查看目的端口來分離外來的分組。它必須查看套接口對的所有四個元素才能確定由哪個端點接收到達的分組。對于上面的例子,對于端口21存在三個套接口,如果一個分組來自端口1300,目的地為端口 21,那么它就傳送給第一個子進程;如果一個分組來自23端口1301,目的地為端口 21,那么它就傳送給第二個子進程;所有其它的目的端口21的TCO分組則傳送給擁有監(jiān)聽套接口的初始服務器(父進程)。4.3.3 緩沖區(qū)大小及其限制由于通信雙方及中間節(jié)點的配置不同,有些會影響應用程序數(shù)據(jù)的傳輸。影響IP數(shù)據(jù)報大小的主要限制有:1. IPv4數(shù)據(jù)報的最大值為65535字節(jié),包括IPv4的頭部,總長度字段占16位。2. IPv6數(shù)據(jù)報的最大值為65575字節(jié),包括40字節(jié)的IPv6頭部,有效負載長度字段占16位。這里IPv6的有效負載長度字段不含IPv6頭部,而IPv4的總長度字段包含IPv4頭部。另外,IPv6有一個特大有效負載選項,它把有效負載長度字段擴展到32位,但是這個選項要求MTU超過65535的數(shù)據(jù)鏈路,這個選項是為主機到主機的內(nèi)部連接而設計的,例如HIPPI,它們沒有內(nèi)在的MTU。3. 很多網(wǎng)絡有一個最大傳輸單元MTU,它由硬件規(guī)定。例如以太網(wǎng)的MTU為1500字節(jié)。其它鏈路其MTU可以配置。IPv4要求的最小MTU是68字節(jié),IPv6要求的最小MTU為576字節(jié)。4. 在兩臺主機間的路徑上的最小MTU稱為路徑MTU。1500字節(jié)的以太網(wǎng)MTU是當今常見的路徑MTU。路徑MTU在不同方向可以不相同,因為在因特網(wǎng)中路由是非對稱的。5. 當一個數(shù)據(jù)報將從某個接口發(fā)出時,如果它的大小超過相應鏈路的MTU,IPv4和IPV6都將執(zhí)行分片(fragmentation)操作。各片段到達目的地前不會被重組(reassembling)。IPV4主機對其產(chǎn)生的數(shù)據(jù)報執(zhí)行分片,IPV4路由器對其轉(zhuǎn)發(fā)的數(shù)據(jù)報也執(zhí)行分片。但是,IPv6只在數(shù)據(jù)報產(chǎn)生的主機執(zhí)行分片;IPv6路由器對其轉(zhuǎn)發(fā)的數(shù)據(jù)報不進行分片。事實上,IPv6路由器可以執(zhí)行分片,但只對那些由路由器產(chǎn)生的數(shù)據(jù)報而不是轉(zhuǎn)發(fā)的數(shù)據(jù)報。這時的路由器實際上作為主機運行。例如,大多數(shù)路由器支持Telnet協(xié)議,系統(tǒng)管理員就用它來配置路由器。由路由器的Telnet服務器產(chǎn)生的IP數(shù)據(jù)報是由路由器產(chǎn)生的,而不是路由器轉(zhuǎn)發(fā)的。6. IPv4頭部的DF(“不分片”)位若被設置,那么不管是發(fā)送主機還是轉(zhuǎn)發(fā)路由器都不能對本數(shù)據(jù)報分片。當路由器接收到一個超過其外出鏈路MTU大小且設置了DF位的IPv4數(shù)據(jù)報時,它將產(chǎn)生一個ICMP的“destination unreachable, fragmentation needed but DF bit set(目的地不可達,需要分片但DF位已設置)”出錯消息。由于IPv6路由器不執(zhí)行分片,因此IPv6數(shù)據(jù)報隱含設置了DF位。如果IPv6路由器接收到一個超過其外出鏈路MTU大小的IPv6數(shù)據(jù)報年,它將產(chǎn)生一個ICMPv6的“packet too big(分組太大)”的出錯消息。IPv4的DF位和IPv6的隱含DF位可用于路徑MTU的發(fā)現(xiàn)。例如,如果TCP使用IPv4技術,它發(fā)送的數(shù)據(jù)報都將設置DF位。如果某個中間路由器返回一個ICMP的“destination unreachable, fragmentation needed but DF bit set“錯誤,TCP就減少每個數(shù)據(jù)報的數(shù)據(jù)量并重傳。路徑MTU的發(fā)現(xiàn)對IPv4是可選的,但所有IPv6的實現(xiàn)都必須支持它。7. IPv4和IPv6都定義了最小重組緩沖區(qū)大小:任何IPv4和IPv6的實現(xiàn)都必須支持的最小數(shù)據(jù)報大小。對IPv4和其值為576字節(jié),對IPv6為1500字節(jié)。例如,對IPv4來說,如果不能確信給定的目的主機是否能接收577字節(jié)的數(shù)據(jù)報。所以很多使用UDP的應用程序(DNS、RIP、TFTP、BOOTP、SNMP)避免產(chǎn)生大于576字節(jié)的數(shù)據(jù)報。8. TCP有一個MSS(最大分片大?。?,用于向?qū)Ψ絋CP通告在每個分片中能發(fā)送的最大TCP 數(shù)據(jù)量, 使用MSS的目的是告訴對方其重組緩沖區(qū)的實際值,從而避免分片。MSS經(jīng)常設置成MTU減去IP和TCP頭部的固定長度。在以太網(wǎng)環(huán)境下IPv4的MSS為1460字節(jié),使用IPv6的MSS值為1440字節(jié)(兩者的TCP頭部都為20字節(jié),而IPv4頭部是20字節(jié),IPv6的頭部是40字節(jié))。在TCP的MSS選項中,MSS值是一個16位字段,最大值是65535字節(jié)。這個值適合IPv4,因為IPv4數(shù)據(jù)報中的最大TCP數(shù)據(jù)量為65495字節(jié)(即65535減去IPv4頭部20字節(jié)和TCP頭部20字節(jié))。但是,IPv6有特大有效負荷選項,因此需要使用另外的技術。首先,沒有特大有效負荷選項的IPv6數(shù)據(jù)報中最大的TCP數(shù)據(jù)量為65515字節(jié)(即65535減去TCP頭部20字節(jié))。因此65535這個MSS值被認為是“無限”的特殊值,它只在用到特大有效負荷選項時才有用,而這種情況又要求MTU超過65535。如果TCP使用特大有效負荷選項,并且接收到的對方通告的MSS超過65535,那么它所發(fā)送數(shù)據(jù)報的大小限制就是接口MTU。如果這個值太大(即路徑上某個鏈路的MTU比它?。?,那么路徑MTU的發(fā)現(xiàn)功能將確定這個最小值。4.3.4 TCP發(fā)送圖4-7說明了應用程序發(fā)送數(shù)據(jù)到TCP套接口的過程。用戶進程應用進程緩沖區(qū)(大小任意)應用進程內(nèi)核套接口發(fā)送緩沖區(qū)TCPMSS大小的TCP分片MSSMTU-40(IPv4)或-60(IPv6)IPMTU大小的IPv4或IPv6分組輸出隊列數(shù)據(jù)鏈路圖4-7 應用程序發(fā)送數(shù)據(jù)到TCP套接口的過程每個TCP套接口都有一個發(fā)送緩沖區(qū),用戶可以使用SO_SNDBUF套接口選項來改變這個緩沖區(qū)的大小。當應用程序調(diào)用write時,內(nèi)核從應用進程的緩沖區(qū)中拷貝所有數(shù)據(jù)到套接口的發(fā)送緩沖區(qū)。如果套接口的發(fā)送緩沖區(qū)不能存放應用程序的所有數(shù)據(jù)(即應用程序的緩沖區(qū)大于套接口發(fā)送緩沖區(qū),或者套接口發(fā)送緩沖區(qū)還有其它數(shù)據(jù)),應用程序?qū)⒈粧炱穑ㄋ撸?,這里假設套接口是阻塞的(缺省設置)。內(nèi)核將不從write系統(tǒng)調(diào)用返回,直到應用進程緩沖區(qū)中的所有數(shù)據(jù)都拷貝到套接口發(fā)送緩沖區(qū)。所以從寫一個TCP套接口的write調(diào)用成功返回僅表示可以重新使用應用進程的緩沖區(qū)。它并不能告訴用戶對方的TCP或?qū)Ψ綉眠M程已接收到數(shù)據(jù)。TCP取出套接口發(fā)送緩沖區(qū)的數(shù)據(jù)并把它發(fā)送給對方TCP,其過程基于TCP數(shù)據(jù)傳送的所有規(guī)則。對方TCP必須確認收到的數(shù)據(jù),只有收到對方的ACK,發(fā)送方TCP才能刪除套接口發(fā)送緩沖區(qū)中已確認的數(shù)據(jù)。TCP必須保留數(shù)據(jù)拷貝直到對方確認為止。TCP以MSS大小或者更小的塊發(fā)送數(shù)據(jù)給IP(它同時給每個數(shù)據(jù)塊填上TCP頭部以構成分片),其中MSS是由對方通告的,當對方未通告時使用536這個值。IP給每個TCP分片填上IP頭部以構成數(shù)據(jù)報,查找其目的IP地址的路由表項以確定外出接口,然后把數(shù)據(jù)報傳遞給相應的數(shù)據(jù)鏈路。IP可能先將數(shù)據(jù)報分段,再傳送給鏈路層。但如上所述,MSS選項的目的是避免分片,而新的實現(xiàn)又使用路徑MTU發(fā)現(xiàn)功能。每個鏈路有一個輸出隊列,如果輸出隊列滿,則分組丟棄,并沿協(xié)議棧向上返回一個錯誤。TCP將注意這個錯誤,并在以后的某個時刻重傳這個分片,但應用進程不知道這些細節(jié)。4.3.5 UDP發(fā)送圖4-8說明了應用程序發(fā)送數(shù)據(jù)到UDP套接口的過程。用戶進程應用進程緩沖區(qū)應用進程內(nèi)核套接口發(fā)送緩沖區(qū)UDPUDP數(shù)據(jù)報 IPMTU大小的IPv4或IPv6分組輸出隊列數(shù)據(jù)鏈路圖4-8 應用程序發(fā)送數(shù)據(jù)到UDP套接口的過程在圖4-8中,套接口發(fā)送緩沖區(qū)用虛線框,因為它并不存在。UDP套接口有發(fā)送緩沖區(qū)的大?。ㄓ脩艨梢允褂肧O_SNDBUF套接口選項修改),但是它僅僅是發(fā)送(sendto)到套接口的UDP數(shù)據(jù)報的上限。如果應用程序發(fā)送一個大于套接口發(fā)送緩沖區(qū)的數(shù)據(jù)報,則返回EMSGSIZE錯誤。由于UDP是一種不可靠的服務,它不必保存應用程序的數(shù)據(jù)拷貝,因此不需要一個真正的緩沖區(qū)。(應用進程的數(shù)據(jù)沿協(xié)議棧向下傳遞時,以某種形式拷貝到內(nèi)核的緩沖區(qū),當鏈路層把數(shù)據(jù)傳出后這個拷貝將丟棄。)UDP簡單地填加它的8個字節(jié)的頭部以構成數(shù)據(jù)報并把它傳遞給IP。IPv4或IPv6給它填加相應的IP頭部,執(zhí)行路由操作確定外出接口,然后或者直接將數(shù)據(jù)報加入鏈路層輸出隊列(如果適合于MTU),或者分段后在把每個段加入數(shù)據(jù)鏈路層的輸出隊列。如果UDP應用進程發(fā)送一個大的數(shù)據(jù)報(例如2000字節(jié)數(shù)據(jù)報),它比TCP應用進程更有可能分片,因為TCP會將應用進程數(shù)據(jù)分成MSS大小的塊,但UDP卻沒有這個能力。從寫UDP套接口的sendto調(diào)用成功返回表示數(shù)據(jù)報或所有片段已被加入鏈路層的輸出隊列。如果輸出隊列沒有足夠的空間存放數(shù)據(jù)報或它的某個分片,UDP將返回應用進程ENOBUFS錯誤。這里需要注意的是,有些UDP的實現(xiàn)不返回這種錯誤,這樣甚至數(shù)據(jù)報未經(jīng)發(fā)出就丟失的情況應用進程也不知道。4.4 網(wǎng)絡服務員工作模式當用戶開發(fā)一個服務器程序時,有如下類型的進程控制方法可供選擇:l 迭代服務器程序。這種方式主要用于簡單的網(wǎng)絡服務。它的主要缺點是在當前顧客服務完成之前,新到達的顧客無法得到服務。l 并發(fā)服務器程序,它為每個顧客fork一個子進程提供服務,這是Unix服務器程序通常的做法。l 使用select調(diào)用在一個進程內(nèi)同時服務多個顧客的TCP服務器程序。l 使用線程替代進程實現(xiàn)的并發(fā)服務器程序。本節(jié)中介紹兩種新的并發(fā)程序設計方法:l 預先派生子進程(preforking)。服務器啟動后就派生一組子進程,形成一個子進程池。沒當?shù)絹硪粋€顧客請求,就從進程池內(nèi)選擇一個可用子進程為它服務。l 預先創(chuàng)建線程(prethreading)。服務器啟動后就創(chuàng)建一組線程,形成一個線程池。每個顧客請求由池中的一個線程提供服務。 4.4.1 TCP迭代服務器程序迭代服務器總是在完全處理了一個顧客的請求后,才響應下一個顧客的請求。這種方式主要用于簡單的網(wǎng)絡服務,下面程序給出了使用迭代方法實現(xiàn)的一個簡單的時間/日期服務器程序。#includeunp.h#includeintmain(int argc, char *argv)intlistenfd, connfd;struct sockaddr_inservaddr;charbuffMAXLINE;time_tticks;listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr);servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(13);/* daytime server */Bind(listenfd, (SA *) &servaddr, sizeof(servaddr);Listen(listenfd, LISTENQ);for ( ; ; ) connfd = Accept(listenfd, (SA *) NULL, NULL); ticks = time(NULL); snprintf(buff, sizeof(buff), %.24srn, ctime(&ticks); Write(connfd, buff, strlen(buff);Close(connfd);從進程控制的角度來看,迭代服務器是最快的,因為它不進行進程控制。4.4.2 TCP并發(fā)服務器程序傳統(tǒng)上,并發(fā)服務器是調(diào)用fork派生一個子進程來處理顧客的請求。這使得服務器可在同一時間為多個顧客提供服務。唯一的限制是操作系統(tǒng)對同一用戶可擁有的進程數(shù)量的限制。下面的程序例子是一個并發(fā)服務器的實現(xiàn)。絕大多數(shù)TCP服務器程序也是這樣編寫的。#includeunp.hintmain(int argc, char *argv)intlistenfd, connfd;pid_tchildpid;voidsig_chld(int), sig_int(int), web_child(int);socklen_tclilen, addrlen;struct sockaddr*cliaddr;if (argc = 2)listenfd = Tcp_listen(NULL, argv1, &addrlen);else if (argc = 3)listenfd = Tcp_listen(argv1, argv2, &addrlen);elseerr_quit(usage: serv01 );cliaddr = Malloc(addrlen);Signal(SIGCHLD, sig_chld);Signal(SIGINT, sig_int);for ( ; ; ) clilen = addrlen;if ( (connfd = accept(listenfd, cliaddr, &clilen) 0) if (errno = EINTR)continue;/* back to for() */elseerr_sys(accept error);if ( (childpid = Fork() = 0) /* child process */Close(listenfd);/* close listening socket */web_child(connfd);/* process the request */exit(0);Close(connfd);/* parent closes connected socket */* end serv01 */并發(fā)服務器的問題在于fork子進程時所消耗的CPU時間。20世紀80年代后期,當一個服務器一天只需處理幾百、幾千個顧客請求時,這樣實現(xiàn)從性能上是能夠滿足的。然而到了Web時代,一個重負荷的Web服務器一天的訪問數(shù)量以百萬計。這種情況下,就單臺主機而言,對于最繁忙的站點往往運行多臺主機來分攤負載。改進服務器性能的方法有以下幾種??梢圆捎妙A先派生子進程技術來提高并發(fā)服務器的性能。預先派生子進程服務器程序不再為每個顧客請求fork一個子進程,而是在服務器啟動時就預先派生一組子進程,做好為接入的顧客請求服務的準備。圖4-9顯示了一個預先派生N個子進程的服務器正在為2個顧客同時服務的情形。顧客1子進程1顧客2子進程2父進程子進程3可用子進程池.子進程N圖4-9 預先派生子進程的并發(fā)服務器使用預先派生子進程的描述代碼如下:#includeunp.hstatic intnchildren;static pid_t*pids;intmain(int argc, char *argv)intlistenfd, i;socklen_taddrlen;voidsig_int(int);pid_tchild_make(int, int, int);if (argc = 3)listenfd = Tcp_listen(NULL, argv1, &addrlen);else if (argc = 4)listenfd = Tcp_listen(argv1, argv2, &addrlen);elseerr_quit(usage: serv02 );nchildren = atoi(argvargc-1);pids = Calloc(nchildren, sizeof(pid_t);for (i = 0; i nchildren; i+)pidsi = child_make(i, listenfd, addrlen);/* parent returns */Signal(SIGINT, sig_int);for ( ; ; )pause();/* everything done by children */這種技術的優(yōu)點在于:不需要引入父進程執(zhí)行fork的開銷,新的顧客請求就能得到服務。而缺點在于:每次啟動服務器時,父進程必須確定需要產(chǎn)生多少個子進程。如果不考慮再派生子進程,一旦所有子進程都被顧客請求占用,此時新到的請求將被暫時忽略,直到有一個子進程可用。對于父進程可以監(jiān)視可用子進程數(shù),一旦低于某個系統(tǒng)預先設定的閥值就再派生額外的子進程。同樣,如果空閑子進程數(shù)大于某個閥值,則父進程將終止部分新派生的子進程。因為過多的子進程會占用系統(tǒng)的資源,從而導致系統(tǒng)性能下降。當系統(tǒng)負載較輕時,傳統(tǒng)的并發(fā)服務器模型能夠很好地處理顧客的請求,也就是每來一個請求,服務器就派生一個子進程為之服務。它甚至可以和inetd結(jié)合使用,由inetd負責接收每個連接。對于重負載情況,例如web服務器,可以使用相關的技術增強服務器的處理能力。4.4.3 4.4BSD上的實現(xiàn)在源自Berkeley的內(nèi)核實現(xiàn)上,父進程在派生子進程之前創(chuàng)建監(jiān)聽套接口,而每次fork子進程時,各個子進程復制父進程的全部描述字。圖4-10描述了proc結(jié)構(每個進程一個)、監(jiān)聽描述字的單個file結(jié)構以及單個socket結(jié)構的關系。在proc結(jié)構中,描述字只是某個數(shù)組的一個下標,用于引用一個file結(jié)構。而fork派生子進程時,子進程復制描述字的特性之一就是:子進程中給定的描述字所引用的file結(jié)構與父進程中同一描述字所引用的file結(jié)構一致。每個file結(jié)構有一個訪問計數(shù),它在文件或者套接口打開時為1,而每當調(diào)用fork或者dup本描述字時,它就增加1。在具有N個子進程的例子中,file結(jié)構的訪問計數(shù)為N+1(父進程雖然從不調(diào)用accept,但它并未關閉該監(jiān)聽描述字)。當程序啟動后,N個子進程被派生,它們分別調(diào)用accept并由內(nèi)核置入睡眠狀態(tài)。當?shù)谝粋€顧客連接到來時,N個睡眠進程均被喚醒。這是由于這N個進程共享一個socket結(jié)構,導致它們睡眠在同一等待通道(wait channel),即socket結(jié)構的so_timeo成員上。但是,雖然N個進程同時喚醒,只有最先被調(diào)度的進程才能獲得顧客連接,而其它N-1個進程在執(zhí)行過程中,它們會發(fā)現(xiàn)隊列長度為0(連接已被取走),因此被再次投入睡眠。這通常被稱為驚群(thundering herd)問題,因為盡管只有一個進程可以獲得連接,但所有進程都被喚醒。這樣雖然可以工作,但這種情況會導致系統(tǒng)性能的下降。為了避免驚群問題的發(fā)生,用戶不希望有額外子進程空閑,某些Unix內(nèi)核有一個名字為wa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論